summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgit.mk1
-rw-r--r--cmd.c7
m---------git0
-rw-r--r--parsing.c2
-rw-r--r--shared.c2
-rw-r--r--ui-blame.c4
-rw-r--r--ui-blob.c14
-rw-r--r--ui-plain.c4
-rw-r--r--ui-shared.c10
-rw-r--r--ui-shared.h3
-rw-r--r--ui-snapshot.c2
-rw-r--r--ui-tree.c8
-rw-r--r--ui-wiki.c213
-rw-r--r--ui-wiki.h6
14 files changed, 258 insertions, 18 deletions
diff --git a/cgit.mk b/cgit.mk
index 3fcc1ca..6c9e610 100644
--- a/cgit.mk
+++ b/cgit.mk
@@ -94,6 +94,7 @@ CGIT_OBJ_NAMES += ui-stats.o
CGIT_OBJ_NAMES += ui-summary.o
CGIT_OBJ_NAMES += ui-tag.o
CGIT_OBJ_NAMES += ui-tree.o
+CGIT_OBJ_NAMES += ui-wiki.o
CGIT_OBJS := $(addprefix $(CGIT_PREFIX),$(CGIT_OBJ_NAMES))
diff --git a/cmd.c b/cmd.c
index 3342843..64a00f6 100644
--- a/cmd.c
+++ b/cmd.c
@@ -26,6 +26,7 @@
#include "ui-summary.h"
#include "ui-tag.h"
#include "ui-tree.h"
+#include "ui-wiki.h"
static void HEAD_fn(void)
{
@@ -164,6 +165,11 @@ static void tree_fn(void)
cgit_print_tree(ctx.qry.oid, ctx.qry.path);
}
+static void wiki_fn(void)
+{
+ cgit_print_wiki(ctx.qry.oid);
+}
+
#define def_cmd(name, want_repo, want_vpath, is_clone) \
{#name, name##_fn, want_repo, want_vpath, is_clone}
@@ -191,6 +197,7 @@ struct cgit_cmd *cgit_get_cmd(void)
def_cmd(summary, 1, 0, 0),
def_cmd(tag, 1, 0, 0),
def_cmd(tree, 1, 1, 0),
+ def_cmd(wiki, 1, 0, 0),
};
int i;
diff --git a/git b/git
-Subproject c44beea485f0f2feaf460e2ac87fdd5608d63cf
+Subproject 81f86aacc4eb74cdb9c2c8082d36d2070c66604
diff --git a/parsing.c b/parsing.c
index 5616d43..115ce81 100644
--- a/parsing.c
+++ b/parsing.c
@@ -200,7 +200,7 @@ struct taginfo *cgit_parse_tag(struct tag *tag)
const char *p;
struct taginfo *ret = NULL;
- data = repo_read_object_file(the_repository, &tag->object.oid, &type, &size);
+ data = odb_read_object(the_repository->objects, &tag->object.oid, &type, &size);
if (!data || type != OBJ_TAG)
goto cleanup;
diff --git a/shared.c b/shared.c
index 5605cf0..1c2d682 100644
--- a/shared.c
+++ b/shared.c
@@ -243,7 +243,7 @@ static int load_mmfile(mmfile_t *file, const struct object_id *oid)
file->ptr = (char *)"";
file->size = 0;
} else {
- file->ptr = repo_read_object_file(the_repository, oid, &type,
+ file->ptr = odb_read_object(the_repository->objects, oid, &type,
(unsigned long *)&file->size);
}
return 1;
diff --git a/ui-blame.c b/ui-blame.c
index d07b67f..9c575ef 100644
--- a/ui-blame.c
+++ b/ui-blame.c
@@ -121,14 +121,14 @@ static void print_object(const struct object_id *oid, const char *path,
struct blame_origin *o;
struct blame_entry *ent = NULL;
- type = oid_object_info(the_repository, oid, &size);
+ type = odb_read_object_info(the_repository->objects, oid, &size);
if (type == OBJ_BAD) {
cgit_print_error_page(404, "Not found", "Bad object name: %s",
oid_to_hex(oid));
return;
}
- buf = repo_read_object_file(the_repository, oid, &type, &size);
+ buf = odb_read_object(the_repository->objects, oid, &type, &size);
if (!buf) {
cgit_print_error_page(500, "Internal server error",
"Error reading object %s", oid_to_hex(oid));
diff --git a/ui-blob.c b/ui-blob.c
index e554fe9..bc91656 100644
--- a/ui-blob.c
+++ b/ui-blob.c
@@ -56,7 +56,7 @@ int cgit_ref_path_exists(const char *path, const char *ref, int file_only)
if (repo_get_oid(the_repository, ref, &oid))
goto done;
- if (oid_object_info(the_repository, &oid, &size) != OBJ_COMMIT)
+ if (odb_read_object_info(the_repository->objects, &oid, &size) != OBJ_COMMIT)
goto done;
read_tree(the_repository,
repo_get_commit_tree(the_repository, lookup_commit_reference(the_repository, &oid)),
@@ -91,18 +91,18 @@ int cgit_print_file(char *path, const char *head, int file_only)
if (repo_get_oid(the_repository, head, &oid))
return -1;
- type = oid_object_info(the_repository, &oid, &size);
+ type = odb_read_object_info(the_repository->objects, &oid, &size);
if (type == OBJ_COMMIT) {
commit = lookup_commit_reference(the_repository, &oid);
read_tree(the_repository, repo_get_commit_tree(the_repository, commit),
&paths, walk_tree, &walk_tree_ctx);
if (!walk_tree_ctx.found_path)
return -1;
- type = oid_object_info(the_repository, &oid, &size);
+ type = odb_read_object_info(the_repository->objects, &oid, &size);
}
if (type == OBJ_BAD)
return -1;
- buf = repo_read_object_file(the_repository, &oid, &type, &size);
+ buf = odb_read_object(the_repository->objects, &oid, &type, &size);
if (!buf)
return -1;
buf[size] = '\0';
@@ -147,13 +147,13 @@ void cgit_print_blob(const char *hex, char *path, const char *head, int file_onl
}
}
- type = oid_object_info(the_repository, &oid, &size);
+ type = odb_read_object_info(the_repository->objects, &oid, &size);
if ((!hex) && type == OBJ_COMMIT && path) {
commit = lookup_commit_reference(the_repository, &oid);
read_tree(the_repository, repo_get_commit_tree(the_repository, commit),
&paths, walk_tree, &walk_tree_ctx);
- type = oid_object_info(the_repository, &oid, &size);
+ type = odb_read_object_info(the_repository->objects, &oid, &size);
}
if (type == OBJ_BAD) {
@@ -162,7 +162,7 @@ void cgit_print_blob(const char *hex, char *path, const char *head, int file_onl
return;
}
- buf = repo_read_object_file(the_repository, &oid, &type, &size);
+ buf = odb_read_object(the_repository->objects, &oid, &type, &size);
if (!buf) {
cgit_print_error_page(500, "Internal server error",
"Error reading object %s", hex);
diff --git a/ui-plain.c b/ui-plain.c
index 4d69607..0301439 100644
--- a/ui-plain.c
+++ b/ui-plain.c
@@ -24,13 +24,13 @@ static int print_object(const struct object_id *oid, const char *path)
char *buf, *mimetype;
unsigned long size;
- type = oid_object_info(the_repository, oid, &size);
+ type = odb_read_object_info(the_repository->objects, oid, &size);
if (type == OBJ_BAD) {
cgit_print_error_page(404, "Not found", "Not found");
return 0;
}
- buf = repo_read_object_file(the_repository, oid, &type, &size);
+ buf = odb_read_object(the_repository->objects, oid, &type, &size);
if (!buf) {
cgit_print_error_page(404, "Not found", "Not found");
return 0;
diff --git a/ui-shared.c b/ui-shared.c
index 93ab93c..d3cf24b 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -10,6 +10,7 @@
#include "cgit.h"
#include "ui-shared.h"
+#include "ui-blob.h"
#include "cmd.h"
#include "html.h"
#include "version.h"
@@ -348,6 +349,12 @@ void cgit_tree_link(const char *name, const char *title, const char *class,
reporevlink("tree", name, title, class, head, rev, path);
}
+void cgit_wiki_link(const char *name, const char *title, const char *class,
+ const char *head, const char *rev, const char *path)
+{
+ reporevlink("wiki", name, title, class, head, rev, path);
+}
+
void cgit_plain_link(const char *name, const char *title, const char *class,
const char *head, const char *rev, const char *path)
{
@@ -1099,6 +1106,9 @@ void cgit_print_pageheader(void)
else
cgit_tree_link("tree", NULL, hc("tree"), ctx.qry.head,
ctx.qry.oid, ctx.qry.vpath);
+ if (cgit_ref_path_exists(".wiki", ctx.qry.head, 0))
+ cgit_wiki_link("wiki", NULL, hc("wiki"), ctx.qry.head,
+ ctx.qry.oid, NULL);
cgit_commit_link("commit", NULL, hc("commit"),
ctx.qry.head, ctx.qry.oid, ctx.qry.vpath);
cgit_diff_link("diff", NULL, hc("diff"), ctx.qry.head,
diff --git a/ui-shared.h b/ui-shared.h
index f12fa99..65d8f75 100644
--- a/ui-shared.h
+++ b/ui-shared.h
@@ -24,6 +24,9 @@ extern void cgit_tag_link(const char *name, const char *title,
extern void cgit_tree_link(const char *name, const char *title,
const char *class, const char *head,
const char *rev, const char *path);
+extern void cgit_wiki_link(const char *name, const char *title,
+ const char *class, const char *head,
+ const char *rev, const char *path);
extern void cgit_plain_link(const char *name, const char *title,
const char *class, const char *head,
const char *rev, const char *path);
diff --git a/ui-snapshot.c b/ui-snapshot.c
index 3e38cd5..d157222 100644
--- a/ui-snapshot.c
+++ b/ui-snapshot.c
@@ -192,7 +192,7 @@ static int write_sig(const struct cgit_snapshot_format *format,
return 0;
}
- buf = repo_read_object_file(the_repository, note, &type, &size);
+ buf = odb_read_object(the_repository->objects, note, &type, &size);
if (!buf) {
cgit_print_error_page(404, "Not found", "Not found");
return 0;
diff --git a/ui-tree.c b/ui-tree.c
index 5368596..3e87fdb 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -127,7 +127,7 @@ static void print_object(const struct object_id *oid, const char *path, const ch
unsigned long size;
bool is_binary;
- type = oid_object_info(the_repository, oid, &size);
+ type = odb_read_object_info(the_repository->objects, oid, &size);
if (type == OBJ_BAD) {
cgit_print_error_page(404, "Not found",
"Bad object name: %s", oid_to_hex(oid));
@@ -138,7 +138,7 @@ static void print_object(const struct object_id *oid, const char *path, const ch
if (mime) {
is_binary = false;
} else {
- buf = repo_read_object_file(the_repository, oid, &type, &size);
+ buf = odb_read_object(the_repository->objects, oid, &type, &size);
if (!buf) {
cgit_print_error_page(500, "Internal server error",
"Error reading object %s", oid_to_hex(oid));
@@ -259,7 +259,7 @@ static int ls_item(const struct object_id *oid, struct strbuf *base,
ctx.qry.path ? "/" : "", name);
if (!S_ISGITLINK(mode)) {
- type = oid_object_info(the_repository, oid, &size);
+ type = odb_read_object_info(the_repository->objects, oid, &size);
if (type == OBJ_BAD) {
htmlf("<tr><td colspan='3'>Bad object: %s %s</td></tr>",
name,
@@ -286,7 +286,7 @@ static int ls_item(const struct object_id *oid, struct strbuf *base,
}
if (S_ISLNK(mode)) {
html(" -> ");
- buf = repo_read_object_file(the_repository, oid, &type, &size);
+ buf = odb_read_object(the_repository->objects, oid, &type, &size);
if (!buf) {
htmlf("Error reading object: %s", oid_to_hex(oid));
goto cleanup;
diff --git a/ui-wiki.c b/ui-wiki.c
new file mode 100644
index 0000000..9d52525
--- /dev/null
+++ b/ui-wiki.c
@@ -0,0 +1,213 @@
+/* ui-wiki.c: functions for wiki output
+ *
+ * Copyright (C) 2006-2017 cgit Development Team <cgit@lists.zx2c4.com>
+ * Copyright (C) 2025 Freya Murphy <freya@freyacat.org>
+ *
+ * Licensed under GNU General Public License v2
+ * (see COPYING for full license text)
+ */
+
+ #define USE_THE_REPOSITORY_VARIABLE
+
+#include "cgit.h"
+#include "ui-wiki.h"
+#include "html.h"
+#include "ui-shared.h"
+
+ #define WIKI_PATH ".wiki"
+
+struct walk_wiki_context {
+ char *curr_rev;
+ int state;
+ int index;
+};
+
+static void print_page(const struct object_id *oid, const char *path, const char *basename, const char *rev)
+{
+ enum object_type type;
+ unsigned long size;
+ char *buf;
+
+ type = odb_read_object_info(the_repository->objects, oid, &size);
+ if (type == OBJ_BAD) {
+ cgit_print_error_page(404, "Not found",
+ "Bad object name: %s", oid_to_hex(oid));
+ return;
+ }
+
+ buf = odb_read_object(the_repository->objects, oid, &type, &size);
+ if (!buf) {
+ cgit_print_error_page(500, "Internal server error",
+ "Error reading object %s", oid_to_hex(oid));
+ return;
+ }
+
+ html("<div id='summary'>");
+ cgit_open_filter(ctx.repo->about_filter, basename);
+ html_raw(buf, size);
+ cgit_close_filter(ctx.repo->about_filter);
+ html("</div>");
+
+ free(buf);
+}
+
+static int ls_wiki(const struct object_id *oid, const char *pathname, struct walk_wiki_context *walk_wiki_ctx)
+{
+ char *name, *link, *ptr;
+
+ if (isdigit(*pathname)) {
+ long index = strtol(pathname, &ptr, 10);
+ if (ptr && *ptr == '-') {
+ pathname = ptr + 1;
+ walk_wiki_ctx->index = index;
+ }
+ }
+
+ name = xstrdup(pathname);
+ ptr = strrchr(name, '.');
+ if (ptr)
+ *ptr = '\0';
+ link = xstrdup(name);
+ for (ptr = name; *ptr; ptr++) {
+ if (*ptr == '-')
+ *ptr = ' ';
+ }
+ for (ptr = link; *ptr; ptr++)
+ *ptr = tolower(*ptr);
+
+ html("<tr><td class='ls-index'>");
+ htmlf("%d", walk_wiki_ctx->index);
+ html("</td><td class>");
+ cgit_wiki_link(name, NULL, "ls-link", ctx.qry.head, walk_wiki_ctx->curr_rev, link);
+ html("</td></tr>\n");
+
+ walk_wiki_ctx->index++;
+ free(name);
+ free(link);
+ return 0;
+}
+
+static void ls_head(void)
+{
+ cgit_print_layout_start();
+ html("<table summary='wiki listing' class='list'>\n");
+ html("<tr class='nohover'>");
+ html("<th class='left'>Index</th>");
+ html("<th class='left'>Title</th>");
+ html("<th/>");
+ html("</tr>\n");
+}
+
+static void ls_tail(void)
+{
+ html("</table>\n");
+}
+
+static int walk_wiki(const struct object_id *oid, struct strbuf *base,
+ const char *pathname, unsigned mode, void *cbdata)
+{
+ struct walk_wiki_context *walk_wiki_ctx = cbdata;
+
+ if (!strcmp(pathname, WIKI_PATH))
+ return READ_TREE_RECURSIVE;
+
+ if (walk_wiki_ctx->state < 2) {
+ if (walk_wiki_ctx->state == 0) {
+ walk_wiki_ctx->state = 1;
+ ls_head();
+ }
+
+ ls_wiki(oid, pathname, walk_wiki_ctx);
+ } else if (walk_wiki_ctx->state == 2) {
+ const char *name;
+
+ name = pathname;
+ if (isdigit(*name)) {
+ char *ptr;
+ strtol(name, &ptr, 10);
+ if (ptr && *ptr == '-')
+ name = ptr + 1;
+ }
+
+ if (!strncasecmp(name, ctx.qry.path, strlen(ctx.qry.path))) {
+ struct strbuf buffer = STRBUF_INIT;
+
+ strbuf_addbuf(&buffer, base);
+ strbuf_addstr(&buffer, pathname);
+
+ walk_wiki_ctx->state = 3;
+ print_page(oid, pathname, buffer.buf, walk_wiki_ctx->curr_rev);
+ strbuf_release(&buffer);
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Show repo wiki
+ * rev: the commit pointing at the root ui object
+ * path: partial name of a wiki md file
+ */
+void cgit_print_wiki(const char *rev)
+{
+ struct object_id oid;
+ struct commit *commit;
+ struct pathspec_item path_items = {
+ .match = WIKI_PATH,
+ .len = sizeof(WIKI_PATH) - 1,
+ };
+ struct pathspec paths = {
+ .nr = 1,
+ .items = &path_items
+ };
+ struct walk_wiki_context walk_wiki_ctx = {
+ .state = 0,
+ .index = 1
+ };
+
+ if (!rev)
+ rev = ctx.qry.head;
+
+ if (repo_get_oid(the_repository, rev, &oid)) {
+ cgit_print_error_page(404, "Not found",
+ "Invalid revision name: %s", rev);
+ return;
+ }
+ commit = lookup_commit_reference(the_repository, &oid);
+ if (!commit || repo_parse_commit(the_repository, commit)) {
+ cgit_print_error_page(404, "Not found",
+ "Invalid commit reference: %s", rev);
+ return;
+ }
+
+ walk_wiki_ctx.curr_rev = xstrdup(rev);
+
+ // print wiki pages
+ read_tree(the_repository, repo_get_commit_tree(the_repository, commit),
+ &paths, walk_wiki, &walk_wiki_ctx);
+
+ if (walk_wiki_ctx.state == 0) {
+ cgit_print_error_page(404, "Not found", "Wiki not found");
+ goto cleanup;
+ }
+
+ ls_tail();
+
+ // print active wiki page
+ if (ctx.qry.path) {
+ html("<hr>\n");
+
+ walk_wiki_ctx.state = 2;
+ read_tree(the_repository, repo_get_commit_tree(the_repository, commit),
+ &paths, walk_wiki, &walk_wiki_ctx);
+
+ if (walk_wiki_ctx.state == 2)
+ cgit_print_error("Wiki page not found");
+ }
+
+ cgit_print_layout_end();
+
+cleanup:
+ free(walk_wiki_ctx.curr_rev);
+}
diff --git a/ui-wiki.h b/ui-wiki.h
new file mode 100644
index 0000000..7160010
--- /dev/null
+++ b/ui-wiki.h
@@ -0,0 +1,6 @@
+#ifndef UI_WIKI_H
+#define UI_WIKI_H
+
+extern void cgit_print_wiki(const char *rev);
+
+#endif /* UI_TREE_H */