Commit Diff


commit - e375b61e75f835108ca5b2c25273dae050dadb81
commit + 4676a8cbca754e6ff833431bd6794586e612343d
blob - a88f4ca7b5fbc190888c0373f0b3f2c88956191d
blob + aa26ca4cd58486e661a549ecff6640e80b3ea383
--- gotwebd/files/htdocs/gotwebd/gotweb.css
+++ gotwebd/files/htdocs/gotwebd/gotweb.css
@@ -378,6 +378,14 @@ header.subtitle h2 {
 .tree_line_blank {
 	padding: 1px;
 	width: 9.5em;
+}
+#tree_content h2 {
+	margin-top: 40px;
+	padding: 0 20px 0;
+}
+#tree_content pre {
+	padding: 0 20px 20px;
+	white-space: pre-wrap;
 }
 
 #diff {
blob - 769fcfb189a08622b7b60081be7781b819637fad
blob + 667de1ed8c7587e8a3413be3fbbca4f143b31d90
--- gotwebd/got_operations.c
+++ gotwebd/got_operations.c
@@ -704,7 +704,7 @@ got_get_repo_tags(struct request *c, size_t limit)
 }
 
 int
-got_output_repo_tree(struct request *c,
+got_output_repo_tree(struct request *c, char **readme,
     int (*cb)(struct template *, struct got_tree_entry *))
 {
 	const struct got_error *error = NULL;
@@ -718,10 +718,13 @@ got_output_repo_tree(struct request *c,
 	struct got_tree_object *tree = NULL;
 	struct got_tree_entry *te;
 	struct repo_dir *repo_dir = t->repo_dir;
+	const char *name;
+	mode_t mode;
 	char *escaped_name = NULL, *path = NULL;
 	int nentries, i;
 
 	TAILQ_INIT(&refs);
+	*readme = NULL;
 
 	rc = TAILQ_FIRST(&t->repo_commits);
 
@@ -758,6 +761,16 @@ got_output_repo_tree(struct request *c,
 
 	for (i = 0; i < nentries; i++) {
 		te = got_object_tree_get_entry(tree, i);
+
+		name = got_tree_entry_get_name(te);
+		mode = got_tree_entry_get_mode(te);
+		if (!S_ISDIR(mode) && (!strcasecmp(name, "README") ||
+		    !strcasecmp(name, "README.md") ||
+		    !strcasecmp(name, "README.txt"))) {
+			free(*readme);
+			*readme = strdup(name);
+		}
+
 		if (cb(c->tp, te) == -1) {
 			error = got_error(GOT_ERR_CANCELLED);
 			break;
@@ -774,6 +787,8 @@ got_output_repo_tree(struct request *c,
 	free(commit_id);
 	free(tree_id);
 	if (error) {
+		free(*readme);
+		*readme = NULL;
 		if (error->code != GOT_ERR_CANCELLED)
 			log_warnx("%s: %s", __func__, error->msg);
 		return -1;
blob - 4cd99ce853542b1e2a0684ce76da6d122f7cf05a
blob + c480587a135af9f8131850e847e558875813395f
--- gotwebd/gotwebd.h
+++ gotwebd/gotwebd.h
@@ -518,7 +518,7 @@ const struct got_error *got_get_repo_commits(struct re
 const struct got_error *got_get_repo_tags(struct request *, size_t);
 const struct got_error *got_get_repo_heads(struct request *);
 const struct got_error *got_open_diff_for_output(FILE **, struct request *);
-int got_output_repo_tree(struct request *,
+int got_output_repo_tree(struct request *, char **,
     int (*)(struct template *, struct got_tree_entry *));
 const struct got_error *got_open_blob_for_output(struct got_blob_object **,
     int *, int *, struct request *);
blob - ca9d83b7efea61fee6727326f0ff8f14326ef366
blob + e100d9f8db931e55f9e066df37626db272893787
--- gotwebd/pages.tmpl
+++ gotwebd/pages.tmpl
@@ -657,9 +657,15 @@ nextsep(char *s, char **t)
 
 {{ define gotweb_render_tree(struct template *tp) }}
 {!
+	const struct got_error	*error;
 	struct request		*c = tp->tp_arg;
 	struct transport	*t = c->t;
 	struct repo_commit	*rc = TAILQ_FIRST(&t->repo_commits);
+	struct gotweb_url	 url;
+	char			*readme = NULL;
+	int			 binary;
+	const uint8_t		*buf;
+	size_t			 len;
 !}
 <header class='subtitle'>
   <h2>Tree</h2>
@@ -679,9 +685,59 @@ nextsep(char *s, char **t)
   </div>
   <hr />
   <table id="tree">
-    {{ render got_output_repo_tree(c, gotweb_render_tree_item) }}
+    {{ render got_output_repo_tree(c, &readme, gotweb_render_tree_item) }}
   </table>
+  {{ if readme }}
+    {!
+	/* sigh... */
+	t->qs->file = readme;
+	error = got_open_blob_for_output(&t->blob, &t->fd, &binary, c);
+	t->qs->file = NULL;
+
+	if (error) {
+		free(readme);
+		return (-1);
+	}
+
+	/* hum... */
+	memset(&url, 0, sizeof(url));
+	url.index_page = -1;
+	url.page = -1;
+	url.action = BLOB;
+	url.path = t->qs->path;
+	url.file = readme;
+	url.folder = t->qs->folder;
+	url.commit = t->qs->commit;
+    !}
+    {{ if !binary }}
+      <h2>
+        <a href="{{ render gotweb_render_url(c, &url) }}">
+          {{ readme }}
+        </a>
+      </h2>
+      <pre>
+        {!
+		for (;;) {
+			error = got_object_blob_read_block(&len, t->blob);
+			if (error) {
+				free(readme);
+				return (-1);
+			}
+			if (len == 0)
+				break;
+			buf = got_object_blob_get_read_buf(t->blob);
+			if (tp_write(tp, buf, len) == -1) {
+				free(readme);
+				return (-1);
+			}
+		}
+        !}
+      </pre>
+    {{ end }}
+  {{ end }}
 </div>
+{{ finally }}
+{! free(readme); !}
 {{ end }}
 
 {{ define gotweb_render_tree_item(struct template *tp,