gout

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

repo_writer.c (4961B)


      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   html_log_free(writer->log);
     63   atom_free(writer->atom);
     64   if (writer->atom_out) {
     65     writer->fs->fclose(writer->atom_out);
     66   }
     67   atom_free(writer->tags);
     68   if (writer->tags_out) {
     69     writer->fs->fclose(writer->tags_out);
     70   }
     71   html_files_free(writer->files);
     72   free(writer);
     73 }
     74 
     75 void html_repowriter_set_log_cachefile(HtmlRepoWriter* writer,
     76                                        const char* cachefile) {
     77   assert(writer != NULL);
     78   assert(cachefile != NULL);
     79   html_log_set_cachefile(writer->log, cachefile);
     80 }
     81 
     82 void html_repowriter_set_log_commit_limit(HtmlRepoWriter* writer,
     83                                           size_t count) {
     84   assert(writer != NULL);
     85   html_log_set_commit_limit(writer->log, count);
     86 }
     87 
     88 void html_repowriter_set_baseurl(HtmlRepoWriter* writer, const char* baseurl) {
     89   assert(writer != NULL);
     90   assert(baseurl != NULL);
     91   atom_set_baseurl(writer->atom, baseurl);
     92   atom_set_baseurl(writer->tags, baseurl);
     93 }
     94 
     95 void html_repowriter_begin(HtmlRepoWriter* writer) {
     96   assert(writer != NULL);
     97   writer->fs->mkdir("commit", S_IRWXU | S_IRWXG | S_IRWXO);
     98   writer->fs->mkdir("file", S_IRWXU | S_IRWXG | S_IRWXO);
     99 
    100   html_refs_begin(writer->refs);
    101   html_log_begin(writer->log);
    102   atom_begin(writer->atom);
    103   atom_begin(writer->tags);
    104   html_files_begin(writer->files);
    105 }
    106 
    107 void html_repowriter_add_commit(HtmlRepoWriter* writer,
    108                                 const GitCommit* git_commit) {
    109   assert(writer != NULL);
    110   assert(git_commit != NULL);
    111   char filename[PATH_MAX];
    112   int r = snprintf(filename, sizeof(filename), "%s.html", git_commit->oid);
    113   if (r < 0 || (size_t)r >= sizeof(filename)) {
    114     errx(1, "snprintf: filename truncated or error");
    115   }
    116   char* path = path_concat("commit", filename);
    117   atom_add_commit(writer->atom, git_commit, path, "text/html", "");
    118   free(path);
    119 
    120   if (html_log_can_add_commits(writer->log)) {
    121     html_log_add_commit(writer->log, git_commit);
    122     HtmlCommit* commit = html_commit_create(
    123         writer->repo, writer->fs, git_commit->oid, git_commit->summary);
    124     html_commit_begin(commit);
    125     html_commit_add_commit(commit, git_commit);
    126     html_commit_end(commit);
    127     html_commit_free(commit);
    128   }
    129 }
    130 
    131 void html_repowriter_add_reference(HtmlRepoWriter* writer,
    132                                    const GitReference* ref) {
    133   assert(writer != NULL);
    134   assert(ref != NULL);
    135   html_refs_add_ref(writer->refs, ref);
    136   if (ref->type == kReftypeTag) {
    137     GitCommit* commit = ref->commit;
    138     char filename[PATH_MAX];
    139     int r = snprintf(filename, sizeof(filename), "%s.html", commit->oid);
    140     if (r < 0 || (size_t)r >= sizeof(filename)) {
    141       errx(1, "snprintf: filename truncated or error");
    142     }
    143     char* path = path_concat("commit", filename);
    144     atom_add_commit(writer->tags, commit, path, "text/html", ref->shorthand);
    145     free(path);
    146   }
    147 }
    148 
    149 void html_repowriter_add_file(HtmlRepoWriter* writer, const GitFile* file) {
    150   assert(writer != NULL);
    151   assert(file != NULL);
    152   html_files_add_file(writer->files, file);
    153 
    154   HtmlFileBlob* blob =
    155       html_fileblob_create(writer->repo, writer->fs, file->repo_path);
    156   html_fileblob_begin(blob);
    157   html_fileblob_add_file(blob, file);
    158   html_fileblob_end(blob);
    159   html_fileblob_free(blob);
    160 }
    161 
    162 void html_repowriter_end(HtmlRepoWriter* writer) {
    163   assert(writer != NULL);
    164   html_refs_end(writer->refs);
    165   html_log_end(writer->log);
    166   atom_end(writer->atom);
    167   atom_end(writer->tags);
    168   html_files_end(writer->files);
    169 }