Diff options
| -rw-r--r-- | MANUAL.txt | 5 | |
| -rw-r--r-- | source/ui-shared.c | 31 | |
| -rwxr-xr-x | tests/t0110-snapshot.sh | 19 |
3 files changed, 49 insertions, 6 deletions
@@ -517,8 +517,9 @@ snapshots:: and "zip". The special value "all" enables all snapshot formats. All compressors use default settings. Some settings can be influenced with environment variables, for example set ZSTD_CLEVEL=10 in the web server - environment for higher (but slower) zstd compression. Default value: - none. + environment for higher (but slower) zstd compression. A ref with a slash + in its name, such as "release/2.0", has its snapshots named with a dash + in place of the slash. Default value: none. source-filter:: Specifies a command which will be invoked to format plaintext blobs in diff --git a/source/ui-shared.c b/source/ui-shared.c index 81db404..23daa2b 100644 --- a/source/ui-shared.c +++ b/source/ui-shared.c @@ -1864,11 +1864,27 @@ static void compose_snapshot_prefix(struct strbuf *filename, const char *base, c strbuf_addf(filename, "%s-%s", base, ref); } +/* + * Unlike reporevlink, this names rev whenever it is given, even where the + * page's own head is rev, since the link does not carry that head along. + */ +static void snapshot_file_link(const char *name, const char *filename, const char *rev) +{ + const char *delim = repolink(NULL, NULL, "snapshot", NULL, filename); + + if (rev) + url_arg(delim, "id", rev); + html("'>"); + html_txt(name); + html("</a>"); +} + void cgit_print_snapshot_links(const struct cgit_repo *repo, const char *ref, const char *separator) { const struct cgit_snapshot_format *f; struct strbuf filename = STRBUF_INIT; - const char *basename; + const char *basename, *rev = NULL; + char *slash; size_t prefixlen; basename = cgit_snapshot_prefix(repo); @@ -1876,6 +1892,13 @@ void cgit_print_snapshot_links(const struct cgit_repo *repo, const char *ref, co strbuf_addstr(&filename, ref); else compose_snapshot_prefix(&filename, basename, ref); + // The snapshot page works no revision out of a name holding a slash, + // since that name becomes the archive's top directory, so a ref such + // as release/2.0 is spelled with a dash and passed outright. + for (slash = filename.buf; (slash = strchr(slash, '/')); slash++) { + *slash = '-'; + rev = ref; + } prefixlen = filename.len; for (f = cgit_snapshot_formats; f->suffix; f++) { @@ -1886,11 +1909,11 @@ void cgit_print_snapshot_links(const struct cgit_repo *repo, const char *ref, co // A file and its signature are one unit, which the stylesheet // keeps from breaking across lines. html("<span class='snapshot'>"); - snapshot_link(filename.buf, NULL, NULL, NULL, NULL, filename.buf); + snapshot_file_link(filename.buf, filename.buf, rev); if (cgit_snapshot_get_sig(ref, f)) { strbuf_addstr(&filename, SIG_SUFFIX); html(" ("); - snapshot_link("sig", NULL, NULL, NULL, NULL, filename.buf); + snapshot_file_link("sig", filename.buf, rev); html(")"); } else if ( starts_with(f->suffix, ".tar") && @@ -1902,7 +1925,7 @@ void cgit_print_snapshot_links(const struct cgit_repo *repo, const char *ref, co strbuf_setlen(&filename, filename.len - strlen(f->suffix)); strbuf_addstr(&filename, ".tar" SIG_SUFFIX); html(" ("); - snapshot_link("sig", NULL, NULL, NULL, NULL, filename.buf); + snapshot_file_link("sig", filename.buf, rev); html(")"); } html("</span>"); diff --git a/tests/t0110-snapshot.sh b/tests/t0110-snapshot.sh index faebf5e..0f1ca21 100755 --- a/tests/t0110-snapshot.sh +++ b/tests/t0110-snapshot.sh @@ -227,4 +227,23 @@ test_expect_success 'a snapshot and its signature are linked as one unit' ' grep "<span class=.snapshot.><a href=./signed/snapshot/signed-one.tar.gz.>signed-one.tar.gz</a> (<a href=./signed/snapshot/signed-one.tar.gz.asc.>sig</a>)</span>" tmp ' +# A snapshot name is never worked back to a ref holding a slash, so such a +# ref is offered under a dashed name and passed along with it, even from a +# page whose own head is that ref. +test_expect_success 'a ref with a slash is linked under a dashed name' ' + git -C repos/vtags tag release/2.0 HEAD && + git -C repos/vtags branch topic/x HEAD && + cgit_rc vtagsrc "url=vtags/refs/" >tmp && + grep "<a href=./vtags/snapshot/vtags-release-2.0.tar.gz?id=release/2.0.>vtags-release-2.0.tar.gz</a>" tmp && + cgit_rc vtagsrc "url=vtags/commit/&h=topic/x" >tmp && + grep "<a href=./vtags/snapshot/vtags-topic-x.tar.gz?id=topic/x.>vtags-topic-x.tar.gz</a>" tmp +' + +test_expect_success GZIP 'the dashed name serves the ref' ' + cgit_rc vtagsrc "url=vtags/snapshot/vtags-release-2.0.tar.gz&id=release/2.0" >tmp && + grep "^Status: 200" tmp && + strip_headers <tmp >slash.tar.gz && + test "$(gzip -dc slash.tar.gz | git -C repos/vtags get-tar-commit-id)" = "$(git -C repos/vtags rev-parse release/2.0^{commit})" +' + test_done |
