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 }