Merge branch 'mr/gitweb-snapshot'
* mr/gitweb-snapshot: t/gitweb-lib: Split HTTP response with non-GNU sed gitweb: Smarter snapshot names gitweb: Document current snapshot rules via new tests t/gitweb-lib.sh: Split gitweb output into headers and body gitweb: check given hash before trying to create snapshot
This commit is contained in:
commit
2a971012b6
@ -2020,16 +2020,27 @@ sub quote_command {
|
||||
|
||||
# get HEAD ref of given project as hash
|
||||
sub git_get_head_hash {
|
||||
my $project = shift;
|
||||
return git_get_full_hash(shift, 'HEAD');
|
||||
}
|
||||
|
||||
sub git_get_full_hash {
|
||||
return git_get_hash(@_);
|
||||
}
|
||||
|
||||
sub git_get_short_hash {
|
||||
return git_get_hash(@_, '--short=7');
|
||||
}
|
||||
|
||||
sub git_get_hash {
|
||||
my ($project, $hash, @options) = @_;
|
||||
my $o_git_dir = $git_dir;
|
||||
my $retval = undef;
|
||||
$git_dir = "$projectroot/$project";
|
||||
if (open my $fd, "-|", git_cmd(), "rev-parse", "--verify", "HEAD") {
|
||||
my $head = <$fd>;
|
||||
if (open my $fd, '-|', git_cmd(), 'rev-parse',
|
||||
'--verify', '-q', @options, $hash) {
|
||||
$retval = <$fd>;
|
||||
chomp $retval if defined $retval;
|
||||
close $fd;
|
||||
if (defined $head && $head =~ /^([0-9a-fA-F]{40})$/) {
|
||||
$retval = $1;
|
||||
}
|
||||
}
|
||||
if (defined $o_git_dir) {
|
||||
$git_dir = $o_git_dir;
|
||||
@ -5285,6 +5296,43 @@ sub git_tree {
|
||||
git_footer_html();
|
||||
}
|
||||
|
||||
sub snapshot_name {
|
||||
my ($project, $hash) = @_;
|
||||
|
||||
# path/to/project.git -> project
|
||||
# path/to/project/.git -> project
|
||||
my $name = to_utf8($project);
|
||||
$name =~ s,([^/])/*\.git$,$1,;
|
||||
$name = basename($name);
|
||||
# sanitize name
|
||||
$name =~ s/[[:cntrl:]]/?/g;
|
||||
|
||||
my $ver = $hash;
|
||||
if ($hash =~ /^[0-9a-fA-F]+$/) {
|
||||
# shorten SHA-1 hash
|
||||
my $full_hash = git_get_full_hash($project, $hash);
|
||||
if ($full_hash =~ /^$hash/ && length($hash) > 7) {
|
||||
$ver = git_get_short_hash($project, $hash);
|
||||
}
|
||||
} elsif ($hash =~ m!^refs/tags/(.*)$!) {
|
||||
# tags don't need shortened SHA-1 hash
|
||||
$ver = $1;
|
||||
} else {
|
||||
# branches and other need shortened SHA-1 hash
|
||||
if ($hash =~ m!^refs/(?:heads|remotes)/(.*)$!) {
|
||||
$ver = $1;
|
||||
}
|
||||
$ver .= '-' . git_get_short_hash($project, $hash);
|
||||
}
|
||||
# in case of hierarchical branch names
|
||||
$ver =~ s!/!.!g;
|
||||
|
||||
# name = project-version_string
|
||||
$name = "$name-$ver";
|
||||
|
||||
return wantarray ? ($name, $name) : $name;
|
||||
}
|
||||
|
||||
sub git_snapshot {
|
||||
my $format = $input_params{'snapshot_format'};
|
||||
if (!@snapshot_fmts) {
|
||||
@ -5302,28 +5350,27 @@ sub git_snapshot {
|
||||
die_error(403, "Unsupported snapshot format");
|
||||
}
|
||||
|
||||
if (!defined $hash) {
|
||||
$hash = git_get_head_hash($project);
|
||||
my $type = git_get_type("$hash^{}");
|
||||
if (!$type) {
|
||||
die_error(404, 'Object does not exist');
|
||||
} elsif ($type eq 'blob') {
|
||||
die_error(400, 'Object is not a tree-ish');
|
||||
}
|
||||
|
||||
my $name = $project;
|
||||
$name =~ s,([^/])/*\.git$,$1,;
|
||||
$name = basename($name);
|
||||
my $filename = to_utf8($name);
|
||||
$name =~ s/\047/\047\\\047\047/g;
|
||||
my $cmd;
|
||||
$filename .= "-$hash$known_snapshot_formats{$format}{'suffix'}";
|
||||
$cmd = quote_command(
|
||||
my ($name, $prefix) = snapshot_name($project, $hash);
|
||||
my $filename = "$name$known_snapshot_formats{$format}{'suffix'}";
|
||||
my $cmd = quote_command(
|
||||
git_cmd(), 'archive',
|
||||
"--format=$known_snapshot_formats{$format}{'format'}",
|
||||
"--prefix=$name/", $hash);
|
||||
"--prefix=$prefix/", $hash);
|
||||
if (exists $known_snapshot_formats{$format}{'compressor'}) {
|
||||
$cmd .= ' | ' . quote_command(@{$known_snapshot_formats{$format}{'compressor'}});
|
||||
}
|
||||
|
||||
$filename =~ s/(["\\])/\\$1/g;
|
||||
print $cgi->header(
|
||||
-type => $known_snapshot_formats{$format}{'type'},
|
||||
-content_disposition => 'inline; filename="' . "$filename" . '"',
|
||||
-content_disposition => 'inline; filename="' . $filename . '"',
|
||||
-status => '200 OK');
|
||||
|
||||
open my $fd, "-|", $cmd
|
||||
|
@ -52,10 +52,24 @@ gitweb_run () {
|
||||
rm -f gitweb.log &&
|
||||
perl -- "$SCRIPT_NAME" \
|
||||
>gitweb.output 2>gitweb.log &&
|
||||
perl -w -e '
|
||||
open O, ">gitweb.headers";
|
||||
while (<>) {
|
||||
print O;
|
||||
last if (/^\r$/ || /^$/);
|
||||
}
|
||||
open O, ">gitweb.body";
|
||||
while (<>) {
|
||||
print O;
|
||||
}
|
||||
close O;
|
||||
' gitweb.output &&
|
||||
if grep '^[[]' gitweb.log >/dev/null 2>&1; then false; else true; fi
|
||||
|
||||
# gitweb.log is left for debugging
|
||||
# gitweb.output is used to parse http output
|
||||
# gitweb.output is used to parse HTTP output
|
||||
# gitweb.headers contains only HTTP headers
|
||||
# gitweb.body contains body of message, without headers
|
||||
}
|
||||
|
||||
. ./test-lib.sh
|
||||
|
@ -75,4 +75,43 @@ test_expect_success \
|
||||
test_debug 'cat gitweb.output'
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# snapshot hash ids
|
||||
|
||||
test_expect_success 'snapshots: good tree-ish id' '
|
||||
gitweb_run "p=.git;a=snapshot;h=master;sf=tgz" &&
|
||||
grep "Status: 200 OK" gitweb.output
|
||||
'
|
||||
test_debug 'cat gitweb.output'
|
||||
|
||||
test_expect_success 'snapshots: bad tree-ish id' '
|
||||
gitweb_run "p=.git;a=snapshot;h=frizzumFrazzum;sf=tgz" &&
|
||||
grep "404 - Object does not exist" gitweb.output
|
||||
'
|
||||
test_debug 'cat gitweb.output'
|
||||
|
||||
test_expect_success 'snapshots: bad tree-ish id (tagged object)' '
|
||||
echo object > tag-object &&
|
||||
git add tag-object &&
|
||||
git commit -m "Object to be tagged" &&
|
||||
git tag tagged-object `git hash-object tag-object` &&
|
||||
gitweb_run "p=.git;a=snapshot;h=tagged-object;sf=tgz" &&
|
||||
grep "400 - Object is not a tree-ish" gitweb.output
|
||||
'
|
||||
test_debug 'cat gitweb.output'
|
||||
|
||||
test_expect_success 'snapshots: good object id' '
|
||||
ID=`git rev-parse --verify HEAD` &&
|
||||
gitweb_run "p=.git;a=snapshot;h=$ID;sf=tgz" &&
|
||||
grep "Status: 200 OK" gitweb.output
|
||||
'
|
||||
test_debug 'cat gitweb.output'
|
||||
|
||||
test_expect_success 'snapshots: bad object id' '
|
||||
gitweb_run "p=.git;a=snapshot;h=abcdef01234;sf=tgz" &&
|
||||
grep "404 - Object does not exist" gitweb.output
|
||||
'
|
||||
test_debug 'cat gitweb.output'
|
||||
|
||||
|
||||
test_done
|
||||
|
115
t/t9502-gitweb-standalone-parse-output.sh
Executable file
115
t/t9502-gitweb-standalone-parse-output.sh
Executable file
@ -0,0 +1,115 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2009 Mark Rada
|
||||
#
|
||||
|
||||
test_description='gitweb as standalone script (parsing script output).
|
||||
|
||||
This test runs gitweb (git web interface) as a CGI script from the
|
||||
commandline, and checks that it produces the correct output, either
|
||||
in the HTTP header or the actual script output.'
|
||||
|
||||
|
||||
. ./gitweb-lib.sh
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# snapshot file name and prefix
|
||||
|
||||
cat >>gitweb_config.perl <<\EOF
|
||||
|
||||
$known_snapshot_formats{'tar'} = {
|
||||
'display' => 'tar',
|
||||
'type' => 'application/x-tar',
|
||||
'suffix' => '.tar',
|
||||
'format' => 'tar',
|
||||
};
|
||||
|
||||
$feature{'snapshot'}{'default'} = ['tar'];
|
||||
EOF
|
||||
|
||||
# Call check_snapshot with the arguments "<basename> [<prefix>]"
|
||||
#
|
||||
# This will check that gitweb HTTP header contains proposed filename
|
||||
# as <basename> with '.tar' suffix added, and that generated tarfile
|
||||
# (gitweb message body) has <prefix> as prefix for al files in tarfile
|
||||
#
|
||||
# <prefix> default to <basename>
|
||||
check_snapshot () {
|
||||
basename=$1
|
||||
prefix=${2:-"$1"}
|
||||
echo "basename=$basename"
|
||||
grep "filename=.*$basename.tar" gitweb.headers >/dev/null 2>&1 &&
|
||||
"$TAR" tf gitweb.body >file_list &&
|
||||
! grep -v "^$prefix/" file_list
|
||||
}
|
||||
|
||||
test_expect_success setup '
|
||||
test_commit first foo &&
|
||||
git branch xx/test &&
|
||||
FULL_ID=$(git rev-parse --verify HEAD) &&
|
||||
SHORT_ID=$(git rev-parse --verify --short=7 HEAD)
|
||||
'
|
||||
test_debug '
|
||||
echo "FULL_ID = $FULL_ID"
|
||||
echo "SHORT_ID = $SHORT_ID"
|
||||
'
|
||||
|
||||
test_expect_success 'snapshot: full sha1' '
|
||||
gitweb_run "p=.git;a=snapshot;h=$FULL_ID;sf=tar" &&
|
||||
check_snapshot ".git-$SHORT_ID"
|
||||
'
|
||||
test_debug 'cat gitweb.headers && cat file_list'
|
||||
|
||||
test_expect_success 'snapshot: shortened sha1' '
|
||||
gitweb_run "p=.git;a=snapshot;h=$SHORT_ID;sf=tar" &&
|
||||
check_snapshot ".git-$SHORT_ID"
|
||||
'
|
||||
test_debug 'cat gitweb.headers && cat file_list'
|
||||
|
||||
test_expect_success 'snapshot: almost full sha1' '
|
||||
ID=$(git rev-parse --short=30 HEAD) &&
|
||||
gitweb_run "p=.git;a=snapshot;h=$ID;sf=tar" &&
|
||||
check_snapshot ".git-$SHORT_ID"
|
||||
'
|
||||
test_debug 'cat gitweb.headers && cat file_list'
|
||||
|
||||
test_expect_success 'snapshot: HEAD' '
|
||||
gitweb_run "p=.git;a=snapshot;h=HEAD;sf=tar" &&
|
||||
check_snapshot ".git-HEAD-$SHORT_ID"
|
||||
'
|
||||
test_debug 'cat gitweb.headers && cat file_list'
|
||||
|
||||
test_expect_success 'snapshot: short branch name (master)' '
|
||||
gitweb_run "p=.git;a=snapshot;h=master;sf=tar" &&
|
||||
ID=$(git rev-parse --verify --short=7 master) &&
|
||||
check_snapshot ".git-master-$ID"
|
||||
'
|
||||
test_debug 'cat gitweb.headers && cat file_list'
|
||||
|
||||
test_expect_success 'snapshot: short tag name (first)' '
|
||||
gitweb_run "p=.git;a=snapshot;h=first;sf=tar" &&
|
||||
ID=$(git rev-parse --verify --short=7 first) &&
|
||||
check_snapshot ".git-first-$ID"
|
||||
'
|
||||
test_debug 'cat gitweb.headers && cat file_list'
|
||||
|
||||
test_expect_success 'snapshot: full branch name (refs/heads/master)' '
|
||||
gitweb_run "p=.git;a=snapshot;h=refs/heads/master;sf=tar" &&
|
||||
ID=$(git rev-parse --verify --short=7 master) &&
|
||||
check_snapshot ".git-master-$ID"
|
||||
'
|
||||
test_debug 'cat gitweb.headers && cat file_list'
|
||||
|
||||
test_expect_success 'snapshot: full tag name (refs/tags/first)' '
|
||||
gitweb_run "p=.git;a=snapshot;h=refs/tags/first;sf=tar" &&
|
||||
check_snapshot ".git-first"
|
||||
'
|
||||
test_debug 'cat gitweb.headers && cat file_list'
|
||||
|
||||
test_expect_success 'snapshot: hierarchical branch name (xx/test)' '
|
||||
gitweb_run "p=.git;a=snapshot;h=xx/test;sf=tar" &&
|
||||
! grep "filename=.*/" gitweb.headers
|
||||
'
|
||||
test_debug 'cat gitweb.headers'
|
||||
|
||||
test_done
|
Loading…
Reference in New Issue
Block a user