diff options
| author | Lars Hjemli <hjemli@gmail.com> | 2007-06-16 20:20:42 +0200 | 
|---|---|---|
| committer | Lars Hjemli <hjemli@gmail.com> | 2007-06-16 20:20:42 +0200 | 
| commit | ffc69736a606fd8f9a10468cce48b9a37b428944 (patch) | |
| tree | b080c702391244a525fa0e7c97758f7f7fa0c383 | |
| parent | cgit.css: make it validate (diff) | |
| download | cgit-ffc69736a606fd8f9a10468cce48b9a37b428944.tar.gz cgit-ffc69736a606fd8f9a10468cce48b9a37b428944.tar.bz2 cgit-ffc69736a606fd8f9a10468cce48b9a37b428944.zip | |
ui-tree: unify with ui-view, use path to select tree/blob
This teaches ui-tree to show both trees and blobs, thereby making ui-view
superfluous. At the same time, ui-tree is extended to honour the specified
path instead of requiering a tree/blob sha1.
Diffstat (limited to '')
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | cgit.c | 5 | ||||
| -rw-r--r-- | cgit.css | 16 | ||||
| -rw-r--r-- | cgit.h | 8 | ||||
| -rw-r--r-- | shared.c | 3 | ||||
| -rw-r--r-- | ui-commit.c | 3 | ||||
| -rw-r--r-- | ui-tree.c | 194 | ||||
| -rw-r--r-- | ui-view.c | 55 | 
8 files changed, 174 insertions, 112 deletions
| @@ -14,7 +14,7 @@ CGIT_SCRIPT_NAME = cgit.cgi  EXTLIBS = git/libgit.a git/xdiff/lib.a -lz -lcrypto  OBJECTS = shared.o cache.o parsing.o html.o ui-shared.o ui-repolist.o \ -	ui-summary.o ui-log.o ui-view.o ui-tree.o ui-commit.o ui-diff.o \ +	ui-summary.o ui-log.o ui-tree.o ui-commit.o ui-diff.o \  	ui-snapshot.o ui-blob.o  CFLAGS += -Wall @@ -97,14 +97,11 @@ static void cgit_print_repo_page(struct cacheitem *item)  			       cgit_query_path, 1);  		break;  	case CMD_TREE: -		cgit_print_tree(cgit_query_head, cgit_query_sha1, cgit_query_path); +		cgit_print_tree(cgit_query_sha1, cgit_query_path);  		break;  	case CMD_COMMIT:  		cgit_print_commit(cgit_query_head);  		break; -	case CMD_VIEW: -		cgit_print_view(cgit_query_sha1, cgit_query_path); -		break;  	case CMD_DIFF:  		cgit_print_diff(cgit_query_head, cgit_query_sha1, cgit_query_sha2,  				cgit_query_path); @@ -199,10 +199,22 @@ td.filemode {  	font-family: monospace;  } -td.blob { +table.blob { +	margin-top: 0.5em; +	border-top: solid 1px black; +} + +table.blob td.no { +	border-right: solid 1px black; +	color: black; +	background-color: #eee; +	text-align: right; +} + +table.blob td.txt {  	white-space: pre;  	font-family: monospace; -	background-color: white; +	padding-left: 0.5em;  }  table.nowrap td { @@ -25,9 +25,8 @@  #define CMD_COMMIT   2  #define CMD_DIFF     3  #define CMD_TREE     4 -#define CMD_VIEW     5 -#define CMD_BLOB     6 -#define CMD_SNAPSHOT 7 +#define CMD_BLOB     5 +#define CMD_SNAPSHOT 6  /* @@ -215,9 +214,8 @@ extern void cgit_print_snapshot_start(const char *mimetype,  extern void cgit_print_repolist(struct cacheitem *item);  extern void cgit_print_summary();  extern void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *path, int pager); -extern void cgit_print_view(const char *hex, char *path);  extern void cgit_print_blob(struct cacheitem *item, const char *hex, char *path); -extern void cgit_print_tree(const char *rev, const char *hex, char *path); +extern void cgit_print_tree(const char *rev, char *path);  extern void cgit_print_commit(const char *hex);  extern void cgit_print_diff(const char *head, const char *old_hex, const char *new_hex,  			    char *path); @@ -59,7 +59,8 @@ int htmlfd = 0;  int cgit_get_cmd_index(const char *cmd)  { -	static char *cmds[] = {"log", "commit", "diff", "tree", "view", "blob", "snapshot", NULL}; +	static char *cmds[] = {"log", "commit", "diff", "tree", "blob", +			       "snapshot", NULL};  	int i;  	for(i = 0; cmds[i]; i++) diff --git a/ui-commit.c b/ui-commit.c index 1d12bbb..ed5384d 100644 --- a/ui-commit.c +++ b/ui-commit.c @@ -182,8 +182,7 @@ void cgit_print_commit(const char *hex)  	cgit_print_date(info->committer_date, FMT_LONGDATE);  	html("</td></tr>\n");  	html("<tr><th>tree</th><td colspan='2' class='sha1'><a href='"); -	query = fmt("h=%s&id=%s", sha1_to_hex(commit->object.sha1), -		    sha1_to_hex(commit->tree->object.sha1)); +	query = fmt("h=%s", sha1_to_hex(commit->object.sha1));  	html_attr(cgit_pageurl(cgit_query_repo, "tree", query));  	htmlf("'>%s</a></td></tr>\n", sha1_to_hex(commit->tree->object.sha1));        	for (p = commit->parents; p ; p = p->next) { @@ -9,14 +9,56 @@  #include "cgit.h"  char *curr_rev; +char *match_path; +int header = 0; -static int print_entry(const unsigned char *sha1, const char *base, -		       int baselen, const char *pathname, unsigned int mode, -		       int stage) +static void print_object(const unsigned char *sha1, char *path) +{ +	enum object_type type; +	unsigned char *buf; +	unsigned long size, lineno, start, idx; + +	type = sha1_object_info(sha1, &size); +	if (type == OBJ_BAD) { +		cgit_print_error(fmt("Bad object name: %s", +				     sha1_to_hex(sha1))); +		return; +	} + +	buf = read_sha1_file(sha1, &type, &size); +	if (!buf) { +		cgit_print_error(fmt("Error reading object %s", +				     sha1_to_hex(sha1))); +		return; +	} + +	html("<table class='blob'>\n"); +	idx = 0; +	start = 0; +	lineno = 0; +	while(idx < size) { +		if (buf[idx] == '\n') { +			buf[idx] = '\0'; +			htmlf("<tr><td class='no'>%d</td><td class='txt'>", +			      ++lineno); +			html_txt(buf + start); +			html("</td></tr>\n"); +			start = idx + 1; +		} +		idx++; +	} +	html("\n</td></tr>\n"); +	html("</table>\n"); +} + + +static int ls_item(const unsigned char *sha1, const char *base, int baselen, +		   const char *pathname, unsigned int mode, int stage)  {  	char *name;  	enum object_type type;  	unsigned long size = 0; +	char *url, *qry;  	name = xstrdup(pathname);  	type = sha1_object_info(sha1, &size); @@ -26,6 +68,10 @@ static int print_entry(const unsigned char *sha1, const char *base,  		      sha1_to_hex(sha1));  		return 0;  	} +	qry = fmt("h=%s&path=%s%s%s", curr_rev, +		  cgit_query_path ? cgit_query_path : "", +		  cgit_query_path ? "/" : "", pathname); +	url = cgit_pageurl(cgit_query_repo, "tree", qry);  	html("<tr><td class='filemode'>");  	html_filemode(mode);  	html("</td><td "); @@ -36,69 +82,133 @@ static int print_entry(const unsigned char *sha1, const char *base,  			      sha1_to_hex(sha1)));  	} else if (S_ISDIR(mode)) {  		html("class='ls-dir'><a href='"); -		html_attr(cgit_pageurl(cgit_query_repo, "tree", -				       fmt("h=%s&id=%s&path=%s%s/", -					   curr_rev, -					   sha1_to_hex(sha1), -					   cgit_query_path ? cgit_query_path : "", -					   pathname))); +		html_attr(url);  	} else {  		html("class='ls-blob'><a href='"); -		html_attr(cgit_pageurl(cgit_query_repo, "view", -				      fmt("h=%s&id=%s&path=%s%s", curr_rev, -					  sha1_to_hex(sha1), -					  cgit_query_path ? cgit_query_path : "", -					  pathname))); +		html_attr(url);  	}  	htmlf("'>%s</a></td>", name);  	htmlf("<td class='filesize'>%li</td>", size);  	html("<td class='links'><a href='"); -	html_attr(cgit_pageurl(cgit_query_repo, "log", -			       fmt("h=%s&path=%s%s", -				   curr_rev, -				   cgit_query_path ? cgit_query_path : "", -				   pathname))); -	html("'>history</a></td>"); +	qry = fmt("h=%s&path=%s%s%s", curr_rev, +		  cgit_query_path ? cgit_query_path : "", +		  cgit_query_path ? "/" : "", pathname); +	url = cgit_pageurl(cgit_query_repo, "log", qry); +	html_attr(url); +	html("' class='button'>H</a></td>");  	html("</tr>\n");  	free(name);  	return 0;  } -void cgit_print_tree(const char *rev, const char *hex, char *path) +static void ls_head() +{ +	html("<table class='list'>\n"); +	html("<tr class='nohover'>"); +	html("<th class='left'>Mode</th>"); +	html("<th class='left'>Name</th>"); +	html("<th class='right'>Size</th>"); +	html("<th/>"); +	html("</tr>\n"); +	header = 1; +} + +static void ls_tail() +{ +	if (!header) +		return; +	html("</table>\n"); +	header = 0; +} + +static void ls_tree(const unsigned char *sha1, char *path)  {  	struct tree *tree; + +	tree = parse_tree_indirect(sha1); +	if (!tree) { +		cgit_print_error(fmt("Not a tree object: %s", +				     sha1_to_hex(sha1))); +		return; +	} + +	ls_head(); +	read_tree_recursive(tree, "", 0, 1, NULL, ls_item); +	ls_tail(); +} + + +static int walk_tree(const unsigned char *sha1, const char *base, int baselen, +		     const char *pathname, unsigned mode, int stage) +{ +	static int state; +	static char buffer[PATH_MAX]; +	char *url; + +	if (state == 0) { +		memcpy(buffer, base, baselen); +		strcpy(buffer+baselen, pathname); +		url = cgit_pageurl(cgit_query_repo, "tree", +				   fmt("h=%s&path=%s", curr_rev, buffer)); +		htmlf(" / <a href='"); +		html_attr(url); +		html("'>"); +		html_txt(xstrdup(pathname)); +		html("</a>"); + +		if (strcmp(match_path, buffer)) +			return READ_TREE_RECURSIVE; + +		if (S_ISDIR(mode)) { +			state = 1; +			ls_head(); +			return READ_TREE_RECURSIVE; +		} else { +			print_object(sha1, buffer); +			return 0; +		} +	} +	ls_item(sha1, base, baselen, pathname, mode, stage); +	return 0; +} + + +/* + * Show a tree or a blob + *   rev:  the commit pointing at the root tree object + *   path: path to tree or blob + */ +void cgit_print_tree(const char *rev, char *path) +{  	unsigned char sha1[20];  	struct commit *commit; +	const char *paths[] = {path, NULL}; + +	if (!rev) +		rev = cgit_query_head;  	curr_rev = xstrdup(rev); -	get_sha1(rev, sha1); +	if (get_sha1(rev, sha1)) { +		cgit_print_error(fmt("Invalid revision name: %s", rev)); +		return; +	}  	commit = lookup_commit_reference(sha1);  	if (!commit || parse_commit(commit)) { -		cgit_print_error(fmt("Invalid head: %s", rev)); +		cgit_print_error(fmt("Invalid commit reference: %s", rev));  		return;  	} -	if (!hex) -		hex = sha1_to_hex(commit->tree->object.sha1); -	if (get_sha1_hex(hex, sha1)) { -		cgit_print_error(fmt("Invalid object id: %s", hex)); -		return; -	} -	tree = parse_tree_indirect(sha1); -	if (!tree) { -		cgit_print_error(fmt("Not a tree object: %s", hex)); +	html("path: <a href='"); +	html_attr(cgit_pageurl(cgit_query_repo, "tree", fmt("h=%s", rev))); +	html("'>root</a>"); + +	if (path == NULL) { +		ls_tree(commit->tree->object.sha1, NULL);  		return;  	} -	html_txt(path); -	html("<table class='list'>\n"); -	html("<tr class='nohover'>"); -	html("<th class='left'>Mode</th>"); -	html("<th class='left'>Name</th>"); -	html("<th class='right'>Size</th>"); -	html("<th/>"); -	html("</tr>\n"); -	read_tree_recursive(tree, "", 0, 1, NULL, print_entry); -	html("</table>\n"); +	match_path = path; +	read_tree_recursive(commit->tree, NULL, 0, 0, paths, walk_tree); +	ls_tail();  } diff --git a/ui-view.c b/ui-view.c deleted file mode 100644 index 8873415..0000000 --- a/ui-view.c +++ /dev/null @@ -1,55 +0,0 @@ -/* ui-view.c: functions to output _any_ object, given it's sha1 - * - * Copyright (C) 2006 Lars Hjemli - * - * Licensed under GNU General Public License v2 - *   (see COPYING for full license text) - */ - -#include "cgit.h" - -void cgit_print_view(const char *hex, char *path) -{ -	unsigned char sha1[20]; -	enum object_type type; -	unsigned char *buf; -	unsigned long size; - -	if (get_sha1_hex(hex, sha1)){ -		cgit_print_error(fmt("Bad hex value: %s", hex)); -	        return; -	} - -	type = sha1_object_info(sha1, &size); -	if (type == OBJ_BAD) { -		cgit_print_error(fmt("Bad object name: %s", hex)); -		return; -	} - -	buf = read_sha1_file(sha1, &type, &size); -	if (!buf) { -		cgit_print_error(fmt("Error reading object %s", hex)); -		return; -	} - -	buf[size] = '\0'; -	html("<table class='list'>\n"); -	html("<tr class='nohover'><th class='left'>"); -	if (path) -		htmlf("%s (", path); -	htmlf("%s %s, %li bytes", typename(type), hex, size); -	if (path) -		html(")"); - -	html(" <a href='"); -	html_attr(cgit_pageurl(cgit_query_repo, "blob",  -			       fmt("id=%s&path=%s",  -				   hex, -				   path))); -	html("'>download</a>"); -	html("</th></tr>\n"); -	html("<tr><td class='blob'>\n"); -	html_txt(buf); -	html("\n</td></tr>\n"); -	html("</table>\n"); -} | 
