gout

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

repo_writer.c (5134B)


      1 #include "writer/html/repo_writer.h"
      2 
      3 #include <assert.h>
      4 #include <err.h>
      5 #include <limits.h>
      6 #include <stdio.h>
      7 #include <stdlib.h>
      8 #include <sys/stat.h>
      9 #include <sys/types.h>
     10 
     11 #include "git/commit.h"
     12 #include "git/file.h"
     13 #include "git/reference.h"
     14 #include "utils.h"
     15 #include "writer/atom/atom.h"
     16 #include "writer/html/commit.h"
     17 #include "writer/html/fileblob.h"
     18 #include "writer/html/files.h"
     19 #include "writer/html/log.h"
     20 #include "writer/html/refs.h"
     21 
     22 struct HtmlRepoWriter {
     23   const GitRepo* repo;
     24   const FileSystem* fs;
     25   HtmlRefs* refs;
     26   HtmlLog* log;
     27   Atom* atom;
     28   FILE* atom_out;
     29   Atom* tags;
     30   FILE* tags_out;
     31   HtmlFiles* files;
     32 };
     33 
     34 HtmlRepoWriter* html_repowriter_create(const GitRepo* repo,
     35                                        const FileSystem* fs) {
     36   assert(repo != NULL);
     37   assert(fs != NULL);
     38   HtmlRepoWriter* writer = ecalloc(1, sizeof(HtmlRepoWriter));
     39   writer->repo = repo;
     40   writer->fs = fs;
     41   writer->refs = html_refs_create(repo, fs);
     42   writer->log = html_log_create(repo, fs);
     43   writer->atom_out = fs->fopen("atom.xml", "w");
     44   if (!writer->atom_out) {
     45     err(1, "fopen: atom.xml");
     46   }
     47   writer->atom = atom_create(repo, writer->atom_out);
     48   writer->tags_out = fs->fopen("tags.xml", "w");
     49   if (!writer->tags_out) {
     50     err(1, "fopen: tags.xml");
     51   }
     52   writer->tags = atom_create(repo, writer->tags_out);
     53   writer->files = html_files_create(repo, fs);
     54   return writer;
     55 }
     56 
     57 void html_repowriter_free(HtmlRepoWriter* writer) {
     58   if (!writer) {
     59     return;
     60   }
     61   html_refs_free(writer->refs);
     62   writer->refs = NULL;
     63   html_log_free(writer->log);
     64   writer->log = NULL;
     65   atom_free(writer->atom);
     66   writer->atom = NULL;
     67   if (writer->atom_out) {
     68     writer->fs->fclose(writer->atom_out);
     69     writer->atom_out = NULL;
     70   }
     71   atom_free(writer->tags);
     72   writer->tags = NULL;
     73   if (writer->tags_out) {
     74     writer->fs->fclose(writer->tags_out);
     75     writer->tags_out = NULL;
     76   }
     77   html_files_free(writer->files);
     78   writer->files = NULL;
     79   free(writer);
     80 }
     81 
     82 void html_repowriter_set_log_cachefile(HtmlRepoWriter* writer,
     83                                        const char* cachefile) {
     84   assert(writer != NULL);
     85   assert(cachefile != NULL);
     86   html_log_set_cachefile(writer->log, cachefile);
     87 }
     88 
     89 void html_repowriter_set_log_commit_limit(HtmlRepoWriter* writer,
     90                                           size_t count) {
     91   assert(writer != NULL);
     92   html_log_set_commit_limit(writer->log, count);
     93 }
     94 
     95 void html_repowriter_set_baseurl(HtmlRepoWriter* writer, const char* baseurl) {
     96   assert(writer != NULL);
     97   assert(baseurl != NULL);
     98   atom_set_baseurl(writer->atom, baseurl);
     99   atom_set_baseurl(writer->tags, baseurl);
    100 }
    101 
    102 void html_repowriter_begin(HtmlRepoWriter* writer) {
    103   assert(writer != NULL);
    104   writer->fs->mkdir("commit", S_IRWXU | S_IRWXG | S_IRWXO);
    105   writer->fs->mkdir("file", S_IRWXU | S_IRWXG | S_IRWXO);
    106 
    107   html_refs_begin(writer->refs);
    108   html_log_begin(writer->log);
    109   atom_begin(writer->atom);
    110   atom_begin(writer->tags);
    111   html_files_begin(writer->files);
    112 }
    113 
    114 void html_repowriter_add_commit(HtmlRepoWriter* writer,
    115                                 const GitCommit* git_commit) {
    116   assert(writer != NULL);
    117   assert(git_commit != NULL);
    118   char filename[PATH_MAX];
    119   int r = snprintf(filename, sizeof(filename), "%s.html", git_commit->oid);
    120   if (r < 0 || (size_t)r >= sizeof(filename)) {
    121     errx(1, "snprintf: filename truncated or error");
    122   }
    123   char* path = path_concat("commit", filename);
    124   atom_add_commit(writer->atom, git_commit, path, "text/html", "");
    125   free(path);
    126 
    127   if (html_log_can_add_commits(writer->log)) {
    128     html_log_add_commit(writer->log, git_commit);
    129     HtmlCommit* commit = html_commit_create(
    130         writer->repo, writer->fs, git_commit->oid, git_commit->summary);
    131     html_commit_begin(commit);
    132     html_commit_add_commit(commit, git_commit);
    133     html_commit_end(commit);
    134     html_commit_free(commit);
    135   }
    136 }
    137 
    138 void html_repowriter_add_reference(HtmlRepoWriter* writer,
    139                                    const GitReference* ref) {
    140   assert(writer != NULL);
    141   assert(ref != NULL);
    142   html_refs_add_ref(writer->refs, ref);
    143   if (ref->type == kReftypeTag) {
    144     GitCommit* commit = ref->commit;
    145     char filename[PATH_MAX];
    146     int r = snprintf(filename, sizeof(filename), "%s.html", commit->oid);
    147     if (r < 0 || (size_t)r >= sizeof(filename)) {
    148       errx(1, "snprintf: filename truncated or error");
    149     }
    150     char* path = path_concat("commit", filename);
    151     atom_add_commit(writer->tags, commit, path, "text/html", ref->shorthand);
    152     free(path);
    153   }
    154 }
    155 
    156 void html_repowriter_add_file(HtmlRepoWriter* writer, const GitFile* file) {
    157   assert(writer != NULL);
    158   assert(file != NULL);
    159   html_files_add_file(writer->files, file);
    160 
    161   HtmlFileBlob* blob =
    162       html_fileblob_create(writer->repo, writer->fs, file->repo_path);
    163   html_fileblob_begin(blob);
    164   html_fileblob_add_file(blob, file);
    165   html_fileblob_end(blob);
    166   html_fileblob_free(blob);
    167 }
    168 
    169 void html_repowriter_end(HtmlRepoWriter* writer) {
    170   assert(writer != NULL);
    171   html_refs_end(writer->refs);
    172   html_log_end(writer->log);
    173   atom_end(writer->atom);
    174   atom_end(writer->tags);
    175   html_files_end(writer->files);
    176 }