summaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c173
1 files changed, 0 insertions, 173 deletions
diff --git a/src/main.c b/src/main.c
deleted file mode 100644
index 5c04467..0000000
--- a/src/main.c
+++ /dev/null
@@ -1,173 +0,0 @@
-#include "arena.h"
-#include "die.h"
-#include "strutil.h"
-#include "creole.h"
-
-// #include <assert.h>
-#include <errno.h> // errno, EEXIST
-#include <git2.h> // git_*
-#include <stdbool.h> // false
-#include <stdio.h>
-#include <stdlib.h> // EXIT_SUCCESS
-#include <sys/stat.h> // mkdir
-#include <sys/types.h> // mode_t
-
-void xmkdir(const char *path, mode_t mode, bool exist_ok) {
- if (mkdir(path, mode) < 0) {
- if (exist_ok && errno == EEXIST) {
- return;
- } else {
- die_errno("failed to mkdir %s", path);
- }
- }
-}
-
-void process_other_file(const char *path, const char *source, size_t source_len) {
- FILE *out = fopen(path, "w");
- printf("Copying: %s\n", path);
- if (out == NULL) {
- die_errno("failed to open %s for writing", path);
- }
- if (fwrite(source, 1, source_len, out) < source_len) {
- die_errno("failed to write content to %s\n", path);
- }
- fclose(out);
-}
-
-void process_markup_file(struct arena *a, const char *path, const char *source, size_t source_len) {
- char *out_path = replace_suffix(a, path, ".txt", ".html");
- printf("Generating: %s\n", out_path);
- FILE *out = fopen(out_path, "w");
- if (out == NULL) {
- die_errno("failed to open %s for writing", path);
- }
- render_creole(out, source, source_len);
- fclose(out);
-}
-
-void process_dir(const char *path) {
- xmkdir(path, 0755, false);
-}
-
-void list_tree(struct arena *a, struct git_repository *repo, struct git_tree *tree, const char *prefix) {
- // Grab a snapshot of the arena.
- // All memory allocated within the arena in this subcalltree will be freed.
- // This is effectively the same as allocating a new arena for each call to list_tree.
- struct arena snapshot = *a;
-
- size_t tree_count = git_tree_entrycount(tree);
- for (size_t i = 0; i < tree_count; ++i) {
- // Read the entry.
- const struct git_tree_entry *entry;
- if ((entry = git_tree_entry_byindex(tree, i)) == NULL) {
- die("read tree item");
- }
-
- // Construct path to entry.
- const char *entry_out_path = joinpath(a, prefix, git_tree_entry_name(entry));
-
- // entry->obj fail on submodules. just ignore them.
- struct git_object *obj;
- if (git_tree_entry_to_object(&obj, repo, entry) == 0) {
- git_object_t type = git_object_type(obj);
- switch (type) {
- case GIT_OBJECT_BLOB: {
- struct git_blob *blob = (struct git_blob *)obj;
- const char *source = git_blob_rawcontent(blob);
- if (source == NULL) {
- die_git("get source for blob %s", git_oid_tostr_s(git_object_id(obj)));
- }
- size_t source_len = git_blob_rawsize(blob);
- if (endswith(entry_out_path, ".txt") && !git_blob_is_binary(blob)) {
- process_markup_file(a, entry_out_path, source, source_len);
- } else {
- process_other_file(entry_out_path, source, source_len);
- }
- git_object_free(obj);
- } break;
- case GIT_OBJECT_TREE: {
- process_dir(entry_out_path);
- list_tree(a, repo, (struct git_tree *)obj, entry_out_path);
- git_object_free(obj);
- } break;
- default: {
- // Ignore whatever weird thing this is.
- git_object_free(obj);
- } break;
- }
- }
- }
-
- // Restore snapshot.
- *a = snapshot;
-}
-
-int main(int argc, char *argv[])
-{
- if (argc != 3) {
- die("Usage: %s git-path out-path", argv[0]);
- }
- char *git_path = argv[1];
- char *out_path = argv[2];
-
- // Initialize libgit. Note that calling git_libgit2_shutdown is not
- // necessary, as per this snippet from the documentation:
- //
- // > Usually you don’t need to call the shutdown function as the operating
- // > system will take care of reclaiming resources, but if your
- // > application uses libgit2 in some areas which are not usually active,
- // > you can use
- //
- // That's good news!
- if (git_libgit2_init() < 0) {
- die_git("initialize libgit");
- }
-
- // Do not search outside the git repository. GIT_CONFIG_LEVEL_APP is the highest level currently.
- // for (int i = 1; i <= GIT_CONFIG_LEVEL_APP; i++) {
- // if (git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, i, "") < 0) {
- // die_git("set search path");
- // }
- // }
-
- // Don't require the repository to be owned by the current user.
- git_libgit2_opts(GIT_OPT_SET_OWNER_VALIDATION, 0);
-
- struct git_repository *repo;
- if (git_repository_open_ext(&repo, git_path, GIT_REPOSITORY_OPEN_NO_SEARCH, NULL) < 0) {
- die_git("open repository");
- }
-
- // Find HEAD.
- struct git_object *head;
- const struct git_oid *head_id;
- if (git_revparse_single(&head, repo, "HEAD") < 0) {
- die_git("parse HEAD");
- }
- head_id = git_object_id(head);
- git_object_free(head);
-
- // Get a handle to the tree at head.
- struct git_commit *commit;
- if (git_commit_lookup(&commit, repo, head_id) < 0) {
- die_git("look up head commit");
- }
- struct git_tree *tree;
- if (git_commit_tree(&tree, commit) < 0) {
- die_git("get tree for commit %s", git_oid_tostr_s(git_commit_id(commit)));
- }
-
- // Create the initial output directory.
- xmkdir(out_path, 0755, true);
-
- struct arena a = arena_create(1024);
- list_tree(&a, repo, tree, out_path);
-#ifndef NDEBUG
- arena_destroy(&a);
-#endif
-
-#ifndef NDEBUG
- git_libgit2_shutdown();
-#endif
- return EXIT_SUCCESS;
-}