so://phie

soso

My pretty neat website
git clone git://soophie.de/soso

blob: 58a3acb504a913a0975813b8864f6b85b43690f5 (3643 bytes)[raw]

1#include "git_repo.h"

2#include "git_repo_blob.h"

3

4#include "../templ/duc_git_repo_blob.h"

5

6static orb_rc_t init(orb_module_t *self) {

7 duc_git_repo_blob_t *data = self->data;

8 git_repo_blob_param_list_t *param_list = self->param_list;

9 if (param_list) {

10 data->repo = param_list->repo;

11 data->is_markdown = param_list->is_markdown;

12 data->is_raw = param_list->is_raw;

13 }

14 return ORB_OK;

15}

16

17static int _fetch_tree_cb(const char *root, const git_tree_entry *entry_handle, void *data) {

18 git_repo_blob_tree_cb_t *handle = data;

19 const char *name = git_tree_entry_name(entry_handle);

20 git_filemode_t mode_handle = git_tree_entry_filemode(entry_handle);

21 if (mode_handle != GIT_FILEMODE_TREE) {

22 const git_oid *oid = git_tree_entry_id(entry_handle);

23 size_t file_path_len = strlen(root) + strlen(name);

24 char file_path[file_path_len + 1];

25 snprintf(file_path, sizeof(file_path), "%s%s", root, name);

26 if (strcmp(handle->file_path, file_path) == 0) {

27 git_oid_cpy(handle->blob_oid, oid);

28 return -1;

29 }

30 }

31 return 0;

32}

33

34static orb_rc_t fetch(orb_module_t *self) {

35 duc_git_repo_blob_t *data = self->data;

36 if (!data->repo) return ORB_FATAL(1);

37 git_oid blob_oid;

38 if (data->repo->flag_oid) {

39 if (git_oid_fromstr(&blob_oid, data->repo->flag_oid) != 0) return ORB_FATAL(2);

40 }

41 if (data->repo->flag_path) {

42 char *ref_oid = NULL;

43 if (data->repo->ref_head) ref_oid = data->repo->ref_head->oid;

44 if (data->repo->ref) ref_oid = data->repo->ref->oid;

45 if (!ref_oid) return ORB_ERR(2);

46 const char *spec_suffix = "^{commit}";

47 size_t spec_len = strlen(ref_oid) + strlen(spec_suffix) + 1;

48 char spec[spec_len];

49 snprintf(spec, spec_len, "%s%s", ref_oid, spec_suffix);

50 git_object *obj = NULL;

51 if (git_revparse_single(&obj, data->repo->handle, spec) == 0) {

52 git_commit *commit_handle = (git_commit *) obj;

53 git_tree *tree_handle = NULL;

54 if (git_commit_tree(&tree_handle, commit_handle) == 0) {

55 git_tree_walk(tree_handle, GIT_TREEWALK_PRE, _fetch_tree_cb, &((git_repo_blob_tree_cb_t) {

56 .blob_oid = &blob_oid,

57 .file_path = data->repo->flag_path,

58 }));

59 git_tree_free(tree_handle);

60 }

61 git_object_free(obj);

62 }

63 if (git_oid_is_zero(&blob_oid)) return ORB_FATAL(3);

64 }

65 git_blob *blob_handle = NULL;

66 if (git_blob_lookup(&blob_handle, data->repo->handle, &blob_oid) != 0) return ORB_FATAL(4);

67 data->blob = calloc(1, sizeof(git_repo_blob_t));

68 git_repo_blob_t *blob = data->blob;

69 char oid_str[GIT_OID_HEXSZ + 1];

70 git_oid_tostr(oid_str, sizeof(oid_str), &blob_oid);

71 blob->oid = strdup(oid_str);

72 blob->name = NULL;

73 size_t size = (size_t) git_blob_rawsize(blob_handle);

74 const char *content = git_blob_rawcontent(blob_handle);

75 if (content) {

76 blob->content = malloc(size + 1);

77 memcpy(blob->content, content, size);

78 blob->content[size] = '\0';

79 blob->size = size;

80 }

81 blob->is_binary = git_blob_is_binary(blob_handle);

82 git_blob_free(blob_handle);

83 return ORB_OK;

84}

85

86static orb_rc_t render(orb_module_t *self, void *out) {

87 return ORB_ERR(duc_git_repo_blob_render(out, (duc_git_repo_blob_t *) self->data));

88}

89

90static void cleanup(orb_module_t *self) {

91 duc_git_repo_blob_t *data = self->data;

92 if (data->blob) {

93 free(data->blob->oid);

94 if (data->blob->name) free(data->blob->name);

95 if (data->blob->content) free(data->blob->content);

96 free(data->blob);

97 data->blob = NULL;

98 }

99}

100

101const orb_module_type_t GIT_REPO_BLOB_TYPE = {

102 .size = sizeof(duc_git_repo_blob_t),

103 .init = init,

104 .fetch = fetch,

105 .render = render,

106 .cleanup = cleanup,

107};