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 }