gout

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

repo_writer.c (5285B)


      1 #include "writer/gopher/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/gopher/commit.h"
     17 #include "writer/gopher/fileblob.h"
     18 #include "writer/gopher/files.h"
     19 #include "writer/gopher/log.h"
     20 #include "writer/gopher/refs.h"
     21 
     22 struct GopherRepoWriter {
     23   const GitRepo* repo;
     24   const FileSystem* fs;
     25   GopherRefs* refs;
     26   GopherLog* log;
     27   Atom* atom;
     28   FILE* atom_out;
     29   Atom* tags;
     30   FILE* tags_out;
     31   GopherFiles* files;
     32 };
     33 
     34 GopherRepoWriter* gopher_repowriter_create(const GitRepo* repo,
     35                                            const FileSystem* fs) {
     36   assert(repo != NULL);
     37   assert(fs != NULL);
     38   GopherRepoWriter* writer = ecalloc(1, sizeof(GopherRepoWriter));
     39   writer->repo = repo;
     40   writer->fs = fs;
     41   writer->refs = gopher_refs_create(repo, fs);
     42   writer->log = gopher_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 = gopher_files_create(repo, fs);
     54   return writer;
     55 }
     56 
     57 void gopher_repowriter_free(GopherRepoWriter* writer) {
     58   if (!writer) {
     59     return;
     60   }
     61   gopher_refs_free(writer->refs);
     62   writer->refs = NULL;
     63   gopher_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   gopher_files_free(writer->files);
     78   writer->files = NULL;
     79   free(writer);
     80 }
     81 
     82 void gopher_repowriter_set_log_cachefile(GopherRepoWriter* writer,
     83                                          const char* cachefile) {
     84   assert(writer != NULL);
     85   assert(cachefile != NULL);
     86   gopher_log_set_cachefile(writer->log, cachefile);
     87 }
     88 
     89 void gopher_repowriter_set_log_commit_limit(GopherRepoWriter* writer,
     90                                             size_t count) {
     91   assert(writer != NULL);
     92   gopher_log_set_commit_limit(writer->log, count);
     93 }
     94 
     95 void gopher_repowriter_set_baseurl(GopherRepoWriter* writer,
     96                                    const char* baseurl) {
     97   assert(writer != NULL);
     98   assert(baseurl != NULL);
     99   atom_set_baseurl(writer->atom, baseurl);
    100   atom_set_baseurl(writer->tags, baseurl);
    101 }
    102 
    103 void gopher_repowriter_begin(GopherRepoWriter* writer) {
    104   assert(writer != NULL);
    105   writer->fs->mkdir("commit", S_IRWXU | S_IRWXG | S_IRWXO);
    106   writer->fs->mkdir("file", S_IRWXU | S_IRWXG | S_IRWXO);
    107 
    108   gopher_refs_begin(writer->refs);
    109   gopher_log_begin(writer->log);
    110   atom_begin(writer->atom);
    111   atom_begin(writer->tags);
    112   gopher_files_begin(writer->files);
    113 }
    114 
    115 void gopher_repowriter_add_commit(GopherRepoWriter* writer,
    116                                   const GitCommit* git_commit) {
    117   assert(writer != NULL);
    118   assert(git_commit != NULL);
    119   char filename[PATH_MAX];
    120   int r = snprintf(filename, sizeof(filename), "%s.gph", git_commit->oid);
    121   if (r < 0 || (size_t)r >= sizeof(filename)) {
    122     errx(1, "snprintf: filename truncated or error");
    123   }
    124   char* path = path_concat("commit", filename);
    125   atom_add_commit(writer->atom, git_commit, path, "", "");
    126   free(path);
    127 
    128   if (gopher_log_can_add_commits(writer->log)) {
    129     gopher_log_add_commit(writer->log, git_commit);
    130     GopherCommit* commit = gopher_commit_create(
    131         writer->repo, writer->fs, git_commit->oid, git_commit->summary);
    132     gopher_commit_begin(commit);
    133     gopher_commit_add_commit(commit, git_commit);
    134     gopher_commit_end(commit);
    135     gopher_commit_free(commit);
    136   }
    137 }
    138 
    139 void gopher_repowriter_add_reference(GopherRepoWriter* writer,
    140                                      const GitReference* ref) {
    141   assert(writer != NULL);
    142   assert(ref != NULL);
    143   gopher_refs_add_ref(writer->refs, ref);
    144   if (ref->type == kReftypeTag) {
    145     GitCommit* commit = ref->commit;
    146     char filename[PATH_MAX];
    147     int r = snprintf(filename, sizeof(filename), "%s.gph", commit->oid);
    148     if (r < 0 || (size_t)r >= sizeof(filename)) {
    149       errx(1, "snprintf: filename truncated or error");
    150     }
    151     char* path = path_concat("commit", filename);
    152     atom_add_commit(writer->tags, commit, path, "", ref->shorthand);
    153     free(path);
    154   }
    155 }
    156 
    157 void gopher_repowriter_add_file(GopherRepoWriter* writer, const GitFile* file) {
    158   assert(writer != NULL);
    159   assert(file != NULL);
    160   gopher_files_add_file(writer->files, file);
    161 
    162   GopherFileBlob* blob =
    163       gopher_fileblob_create(writer->repo, writer->fs, file->repo_path);
    164   gopher_fileblob_begin(blob);
    165   gopher_fileblob_add_file(blob, file);
    166   gopher_fileblob_end(blob);
    167   gopher_fileblob_free(blob);
    168 }
    169 
    170 void gopher_repowriter_end(GopherRepoWriter* writer) {
    171   assert(writer != NULL);
    172   gopher_refs_end(writer->refs);
    173   gopher_log_end(writer->log);
    174   atom_end(writer->atom);
    175   atom_end(writer->tags);
    176   gopher_files_end(writer->files);
    177 }