summaryrefslogtreecommitdiffabout
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--Makefile2
m---------git0
-rw-r--r--html.c20
-rwxr-xr-xtests/setup.sh18
-rwxr-xr-xtests/t0010-validate-html.sh5
-rwxr-xr-xtests/t0101-index.sh6
-rwxr-xr-xtests/t0102-summary.sh6
-rwxr-xr-xtests/t0108-patch.sh37
-rw-r--r--ui-patch.c6
9 files changed, 72 insertions, 28 deletions
diff --git a/Makefile b/Makefile
index 355186e..931c60e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,39 +1,39 @@
CGIT_VERSION = v0.7.2
CGIT_SCRIPT_NAME = cgit.cgi
CGIT_SCRIPT_PATH = /var/www/htdocs/cgit
CGIT_CONFIG = /etc/cgitrc
CACHE_ROOT = /var/cache/cgit
SHA1_HEADER = <openssl/sha.h>
-GIT_VER = 1.5.4.1
+GIT_VER = 1.5.5.rc1
GIT_URL = http://www.kernel.org/pub/software/scm/git/git-$(GIT_VER).tar.bz2
#
# Let the user override the above settings.
#
-include cgit.conf
#
# Define a way to invoke make in subdirs quietly, shamelessly ripped
# from git.git
#
QUIET_SUBDIR0 = +$(MAKE) -C # space to separate -C and subdir
QUIET_SUBDIR1 =
ifneq ($(findstring $(MAKEFLAGS),w),w)
PRINT_DIR = --no-print-directory
else # "make -w"
NO_SUBDIR = :
endif
ifndef V
QUIET_CC = @echo ' ' CC $@;
QUIET_MM = @echo ' ' MM $@;
QUIET_SUBDIR0 = +@subdir=
QUIET_SUBDIR1 = ;$(NO_SUBDIR) echo ' ' SUBDIR $$subdir; \
$(MAKE) $(PRINT_DIR) -C $$subdir
endif
#
# Define a pattern rule for automatic dependency building
#
%.d: %.c
diff --git a/git b/git
-Subproject 527270689c364bea9b0630df9bae5e09c2071c1
+Subproject 803d5158123346229d71de53818920efbc88ca0
diff --git a/html.c b/html.c
index 98ffaf9..937b5e7 100644
--- a/html.c
+++ b/html.c
@@ -27,119 +27,109 @@ char *fmt(const char *format, ...)
va_start(args, format);
len = vsnprintf(buf[bufidx], sizeof(buf[bufidx]), format, args);
va_end(args);
if (len>sizeof(buf[bufidx])) {
fprintf(stderr, "[html.c] string truncated: %s\n", format);
exit(1);
}
return buf[bufidx];
}
void html(const char *txt)
{
write(htmlfd, txt, strlen(txt));
}
void htmlf(const char *format, ...)
{
static char buf[65536];
va_list args;
va_start(args, format);
vsnprintf(buf, sizeof(buf), format, args);
va_end(args);
html(buf);
}
void html_txt(char *txt)
{
char *t = txt;
while(t && *t){
int c = *t;
if (c=='<' || c=='>' || c=='&') {
- *t = '\0';
- html(txt);
- *t = c;
+ write(htmlfd, txt, t - txt);
if (c=='>')
html("&gt;");
else if (c=='<')
html("&lt;");
else if (c=='&')
html("&amp;");
txt = t+1;
}
t++;
}
if (t!=txt)
html(txt);
}
void html_ntxt(int len, char *txt)
{
char *t = txt;
while(t && *t && len--){
int c = *t;
if (c=='<' || c=='>' || c=='&') {
- *t = '\0';
- html(txt);
- *t = c;
+ write(htmlfd, txt, t - txt);
if (c=='>')
html("&gt;");
else if (c=='<')
html("&lt;");
else if (c=='&')
html("&amp;");
txt = t+1;
}
t++;
}
- if (t!=txt) {
- char c = *t;
- *t = '\0';
- html(txt);
- *t = c;
- }
+ if (t!=txt)
+ write(htmlfd, txt, t - txt);
if (len<0)
html("...");
}
void html_attr(char *txt)
{
char *t = txt;
while(t && *t){
int c = *t;
if (c=='<' || c=='>' || c=='\'') {
- *t = '\0';
- html(txt);
- *t = c;
+ write(htmlfd, txt, t - txt);
if (c=='>')
html("&gt;");
else if (c=='<')
html("&lt;");
else if (c=='\'')
html("&quote;");
txt = t+1;
}
t++;
}
if (t!=txt)
html(txt);
}
void html_hidden(char *name, char *value)
{
html("<input type='hidden' name='");
html_attr(name);
html("' value='");
html_attr(value);
html("'/>");
}
void html_option(char *value, char *text, char *selected_value)
{
html("<option value='");
html_attr(value);
html("'");
if (selected_value && !strcmp(selected_value, value))
html(" selected='selected'");
html(">");
html_txt(text);
diff --git a/tests/setup.sh b/tests/setup.sh
index 51d5a75..66bf406 100755
--- a/tests/setup.sh
+++ b/tests/setup.sh
@@ -25,84 +25,92 @@ mkrepo() {
mkdir -p $name
cd $name
git init
for ((n=1; n<=count; n++))
do
echo $n >file-$n
git add file-$n
git commit -m "commit $n"
done
cd $dir
}
setup_repos()
{
rm -rf trash/cache
mkdir -p trash/cache
mkrepo trash/repos/foo 5 >/dev/null
mkrepo trash/repos/bar 50 >/dev/null
cat >trash/cgitrc <<EOF
virtual-root=/
cache-root=$PWD/trash/cache
nocache=0
snapshots=tar.gz tar.bz zip
enable-log-filecount=1
enable-log-linecount=1
summary-log=5
summary-branches=5
summary-tags=5
repo.url=foo
repo.path=$PWD/trash/repos/foo/.git
-repo.desc=the foo repo
+# Do not specify a description for this repo, as it then will be assigned
+# the constant value "[no description]" (which actually used to cause a
+# segfault).
repo.url=bar
repo.path=$PWD/trash/repos/bar/.git
repo.desc=the bar repo
EOF
}
prepare_tests()
{
setup_repos
+ rm -f test-output.log 2>/dev/null
test_count=0
test_failed=0
+ echo "[$0]" "$@" >test-output.log
echo "$@" "($0)"
}
tests_done()
{
printf "\n"
if test $test_failed -gt 0
then
- printf "[%s of %s tests failed]\n" $test_failed $test_count
+ printf "test: *** %s failure(s), logfile=%s\n" \
+ $test_failed "$(pwd)/test-output.log"
false
fi
}
run_test()
{
desc=$1
script=$2
((test_count++))
- eval "$2" >test-output.log
+ printf "\ntest %d: name='%s'\n" $test_count "$desc" >>test-output.log
+ printf "test %d: eval='%s'\n" $test_count "$2" >>test-output.log
+ eval "$2" >>test-output.log 2>>test-output.log
res=$?
+ printf "test %d: exitcode=%d\n" $test_count $res >>test-output.log
if test $res = 0
then
- printf " %s: ok - %s\n" $test_count "$desc"
+ printf " %2d) %-60s [ok]\n" $test_count "$desc"
else
((test_failed++))
- printf " %s: fail - %s\n" $test_count "$desc"
+ printf " %2d) %-60s [failed]\n" $test_count "$desc"
fi
}
cgit_query()
{
CGIT_CONFIG="$PWD/trash/cgitrc" QUERY_STRING="$1" "$PWD/../cgit"
}
cgit_url()
{
CGIT_CONFIG="$PWD/trash/cgitrc" QUERY_STRING="url=$1" "$PWD/../cgit"
}
diff --git a/tests/t0010-validate-html.sh b/tests/t0010-validate-html.sh
index 907a415..94aa52b 100755
--- a/tests/t0010-validate-html.sh
+++ b/tests/t0010-validate-html.sh
@@ -1,31 +1,34 @@
#!/bin/sh
. ./setup.sh
test_url()
{
tidy_opt="-eq"
test -z "$NO_TIDY_WARNINGS" || tidy_opt+=" --show-warnings no"
- cgit_url "$1" | sed -e "1,4d" >trash/tidy-$test_count
+ cgit_url "$1" >trash/tidy-$test_count || return
+ sed -ie "1,4d" trash/tidy-$test_count || return
tidy $tidy_opt trash/tidy-$test_count
rc=$?
+
+ # tidy returns with exitcode 1 on warnings, 2 on error
if test $rc = 2
then
false
else
:
fi
}
prepare_tests 'Validate html with tidy'
run_test 'index page' 'test_url ""'
run_test 'foo' 'test_url "foo"'
run_test 'foo/log' 'test_url "foo/log"'
run_test 'foo/tree' 'test_url "foo/tree"'
run_test 'foo/tree/file-1' 'test_url "foo/tree/file-1"'
run_test 'foo/commit' 'test_url "foo/commit"'
run_test 'foo/diff' 'test_url "foo/diff"'
tests_done
diff --git a/tests/t0101-index.sh b/tests/t0101-index.sh
index 12ed00c..445af6a 100755
--- a/tests/t0101-index.sh
+++ b/tests/t0101-index.sh
@@ -1,13 +1,15 @@
#!/bin/sh
. ./setup.sh
prepare_tests "Check content on index page"
run_test 'generate index page' 'cgit_url "" >trash/tmp'
run_test 'find foo repo' 'grep -e "foo" trash/tmp'
+run_test 'find foo description' 'grep -e "\[no description\]" trash/tmp'
run_test 'find bar repo' 'grep -e "bar" trash/tmp'
-run_test 'no tree-link' 'grep -ve "foo/tree" trash/tmp'
-run_test 'no log-link' 'grep -ve "foo/log" trash/tmp'
+run_test 'find bar description' 'grep -e "the bar repo" trash/tmp'
+run_test 'no tree-link' '! grep -e "foo/tree" trash/tmp'
+run_test 'no log-link' '! grep -e "foo/log" trash/tmp'
tests_done
diff --git a/tests/t0102-summary.sh b/tests/t0102-summary.sh
index 7edd675..f0b0d9a 100755
--- a/tests/t0102-summary.sh
+++ b/tests/t0102-summary.sh
@@ -1,20 +1,20 @@
#!/bin/sh
. ./setup.sh
prepare_tests "Check content on summary page"
run_test 'generate foo summary' 'cgit_url "foo" >trash/tmp'
run_test 'find commit 1' 'grep -e "commit 1" trash/tmp'
run_test 'find commit 5' 'grep -e "commit 5" trash/tmp'
run_test 'find branch master' 'grep -e "master" trash/tmp'
-run_test 'no tags' 'grep -ve "tags" trash/tmp'
+run_test 'no tags' '! grep -e "tags" trash/tmp'
run_test 'generate bar summary' 'cgit_url "bar" >trash/tmp'
-run_test 'no commit 45' 'grep -ve "commit 45" trash/tmp'
+run_test 'no commit 45' '! grep -e "commit 45" trash/tmp'
run_test 'find commit 46' 'grep -e "commit 46" trash/tmp'
run_test 'find commit 50' 'grep -e "commit 50" trash/tmp'
run_test 'find branch master' 'grep -e "master" trash/tmp'
-run_test 'no tags' 'grep -ve "tags" trash/tmp'
+run_test 'no tags' '! grep -e "tags" trash/tmp'
tests_done
diff --git a/tests/t0108-patch.sh b/tests/t0108-patch.sh
new file mode 100755
index 0000000..33351d6
--- a/dev/null
+++ b/tests/t0108-patch.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+. ./setup.sh
+
+prepare_tests "Check content on patch page"
+
+run_test 'generate foo/patch' '
+ cgit_query "url=foo/patch" >trash/tmp
+'
+
+run_test 'find `From:` line' '
+ grep -e "^From: " trash/tmp
+'
+
+run_test 'find `Date:` line' '
+ grep -e "^Date: " trash/tmp
+'
+
+run_test 'find `Subject:` line' '
+ grep -e "^Subject: commit 5" trash/tmp
+'
+
+run_test 'find `cgit` signature' '
+ tail -1 trash/tmp | grep -e "^cgit"
+'
+
+run_test 'find initial commit' '
+ root=$(git --git-dir=$PWD/trash/repos/foo/.git rev-list HEAD | tail -1)
+'
+
+run_test 'generate patch for initial commit' '
+ cgit_query "url=foo/patch&id=$root" >trash/tmp
+'
+
+run_test 'find `cgit` signature' '
+ tail -1 trash/tmp | grep -e "^cgit"
+'
diff --git a/ui-patch.c b/ui-patch.c
index 36bfae4..c1c4ce3 100644
--- a/ui-patch.c
+++ b/ui-patch.c
@@ -61,54 +61,58 @@ static void filepair_cb(struct diff_filepair *pair)
pair->two->sha1, pair->two->path, pair->two->mode);
if (S_ISGITLINK(pair->one->mode) || S_ISGITLINK(pair->two->mode)) {
if (S_ISGITLINK(pair->one->mode))
print_line(fmt("-Subproject %s", sha1_to_hex(pair->one->sha1)), 52);
if (S_ISGITLINK(pair->two->mode))
print_line(fmt("+Subproject %s", sha1_to_hex(pair->two->sha1)), 52);
return;
}
if (cgit_diff_files(pair->one->sha1, pair->two->sha1, print_line))
html("Error running diff");
}
void cgit_print_patch(char *hex)
{
struct commit *commit;
struct commitinfo *info;
unsigned char sha1[20], old_sha1[20];
char *patchname;
if (!hex)
hex = ctx.qry.head;
if (get_sha1(hex, sha1)) {
cgit_print_error(fmt("Bad object id: %s", hex));
return;
}
commit = lookup_commit_reference(sha1);
if (!commit) {
cgit_print_error(fmt("Bad commit reference: %s", hex));
return;
}
info = cgit_parse_commit(commit);
- hashcpy(old_sha1, commit->parents->item->object.sha1);
+
+ if (commit->parents && commit->parents->item)
+ hashcpy(old_sha1, commit->parents->item->object.sha1);
+ else
+ hashclr(old_sha1);
patchname = fmt("%s.patch", sha1_to_hex(sha1));
ctx.page.mimetype = "text/plain";
ctx.page.filename = patchname;
cgit_print_http_headers(&ctx);
htmlf("From %s Mon Sep 17 00:00:00 2001\n", sha1_to_hex(sha1));
htmlf("From: %s%s\n", info->author, info->author_email);
html("Date: ");
cgit_print_date(info->author_date, "%a, %d %b %Y %H:%M:%S %z%n");
htmlf("Subject: %s\n\n", info->subject);
if (info->msg && *info->msg) {
htmlf("%s", info->msg);
if (info->msg[strlen(info->msg) - 1] != '\n')
html("\n");
}
html("---\n");
cgit_diff_tree(old_sha1, sha1, filepair_cb, NULL);
html("--\n");
htmlf("cgit %s\n", CGIT_VERSION);
cgit_free_commitinfo(info);
}