gout

A static git page generator
git clone https://git.bracken.jp/gout.git
Log | Files | Refs | README | LICENSE

log.c (3685B)


      1 #include "writer/html/log.h"
      2 
      3 #include <assert.h>
      4 #include <stdint.h>
      5 #include <stdlib.h>
      6 
      7 #include "format.h"
      8 #include "utils.h"
      9 #include "writer/cache/cache.h"
     10 #include "writer/html/page.h"
     11 
     12 #include <err.h>
     13 #include <sys/stat.h>
     14 #include <unistd.h>
     15 
     16 struct HtmlLog {
     17   const GitRepo* repo;
     18   const FileSystem* fs;
     19   FILE* out;
     20   Cache* cache;
     21   HtmlPage* page;
     22   size_t remaining_commits;
     23   size_t unlogged_commits;
     24 };
     25 
     26 static void write_commit_row(FILE* out, const GitCommit* commit);
     27 
     28 HtmlLog* html_log_create(const GitRepo* repo, const FileSystem* fs) {
     29   assert(repo != NULL);
     30   assert(fs != NULL);
     31   HtmlLog* log = ecalloc(1, sizeof(HtmlLog));
     32   log->repo = repo;
     33   log->fs = fs;
     34   log->out = fs->fopen("log.html", "w");
     35   if (!log->out) {
     36     err(1, "fopen: log.html");
     37   }
     38   log->page = html_page_create(log->out, repo, fs, "Log", "");
     39   log->remaining_commits = SIZE_MAX;
     40   log->unlogged_commits = 0;
     41   return log;
     42 }
     43 
     44 void html_log_free(HtmlLog* log) {
     45   if (!log) {
     46     return;
     47   }
     48   log->fs->fclose(log->out);
     49   log->out = NULL;
     50   cache_free(log->cache);
     51   log->cache = NULL;
     52   html_page_free(log->page);
     53   log->page = NULL;
     54   free(log);
     55 }
     56 
     57 void html_log_set_cachefile(HtmlLog* log, const char* cachefile) {
     58   assert(log != NULL);
     59   assert(cachefile != NULL);
     60   log->cache = cache_open(log->fs, cachefile, write_commit_row);
     61 }
     62 
     63 void html_log_set_commit_limit(HtmlLog* log, size_t count) {
     64   assert(log != NULL);
     65   log->remaining_commits = count;
     66 }
     67 
     68 bool html_log_can_add_commits(const HtmlLog* log) {
     69   assert(log != NULL);
     70   return !log->cache || cache_can_add_commits(log->cache);
     71 }
     72 
     73 void html_log_begin(HtmlLog* log) {
     74   assert(log != NULL);
     75   html_page_begin(log->page);
     76   fprintf(log->out,
     77           "<table id=\"log\"><thead>\n"
     78           "<tr>"
     79           "<td><b>Date</b></td>"
     80           "<td><b>Commit message</b></td>"
     81           "<td><b>Author</b></td>"
     82           "<td class=\"num\" align=\"right\"><b>Files</b></td>"
     83           "<td class=\"num\" align=\"right\"><b>+</b></td>"
     84           "<td class=\"num\" align=\"right\"><b>-</b></td>"
     85           "</tr>\n"
     86           "</thead><tbody>\n");
     87 }
     88 
     89 void html_log_add_commit(HtmlLog* log, const GitCommit* commit) {
     90   assert(log != NULL);
     91   assert(commit != NULL);
     92   if (log->cache) {
     93     cache_add_commit_row(log->cache, commit);
     94   } else if (log->remaining_commits > 0) {
     95     write_commit_row(log->out, commit);
     96     log->remaining_commits--;
     97   } else {
     98     log->unlogged_commits++;
     99   }
    100 }
    101 
    102 void html_log_end(HtmlLog* log) {
    103   assert(log != NULL);
    104   FILE* out = log->out;
    105   if (log->cache) {
    106     cache_close_and_replace(log->cache, log->out);
    107   } else if (log->unlogged_commits > 0) {
    108     size_t count = log->unlogged_commits;
    109     fprintf(out, "<tr><td></td><td colspan=\"5\">");
    110     fprintf(out, "%zu more commits remaining, fetch the repository", count);
    111     fprintf(out, "</td></tr>\n");
    112   }
    113   fprintf(out, "</tbody></table>");
    114   html_page_end(log->page);
    115 }
    116 
    117 static void write_commit_row(FILE* out, const GitCommit* commit) {
    118   assert(out != NULL);
    119   assert(commit != NULL);
    120   fprintf(out, "<tr><td>");
    121   print_time_short(out, commit->author_time);
    122   fprintf(out, "</td><td>");
    123   const char* summary = commit->summary;
    124   if (summary) {
    125     fprintf(out, "<a href=\"commit/%s.html\">", commit->oid);
    126     print_xml_encoded(out, summary);
    127     fprintf(out, "</a>");
    128   }
    129   fprintf(out, "</td><td>");
    130   print_xml_encoded(out, commit->author_name);
    131   fprintf(out,
    132           "</td>"
    133           "<td class=\"num\" align=\"right\">%zu</td>"
    134           "<td class=\"num\" align=\"right\">+%zu</td>"
    135           "<td class=\"num\" align=\"right\">-%zu</td></tr>\n",
    136           commit->filecount, commit->addcount, commit->delcount);
    137 }