#!/bin/sh
# Submodule rows derive their links from the .gitmodules entry at the shown
# revision once enable-gitmodules-links is set, landing on an internal page,
# a plain or rewritten web url, or an unlinked tooltip depending on the url.
# Each of those outcomes is checked against a fixture .gitmodules, along with
# an older revision whose .gitmodules said otherwise, a submodule below the
# top level and the module-link templates that take precedence.
test_description='Check submodule links derived from .gitmodules'
. ./setup.sh
# Every gitlink points at the tip of subtarget, which a link served here leads
# to. The first commit has local-ssh at a url served here, and the second moves
# it elsewhere.
test_expect_success 'set up a parent repo with submodules' '
mkrepo repos/subtarget 2 &&
mkrepo repos/subparent 1 &&
sub=$(git -C repos/subtarget rev-parse HEAD) &&
(
cd repos/subparent &&
for path in local-ssh sibling forge-https forge-ssh opaque cgit-host \
http-url git-url ssh-url file-url near-miss gitlab bitbucket deps/lib
do
git update-index --add --cacheinfo 160000,$sub,$path || return 1
done &&
cat >.gitmodules <<-\EOF &&
[submodule "local-ssh"]
path = local-ssh
url = git@example.com:mirrors/subtarget.git
[submodule "sibling"]
path = sibling
url = ../subtarget.git
[submodule "forge-https"]
path = forge-https
url = https://github.com/example/project.git
[submodule "forge-ssh"]
path = forge-ssh
url = git@github.com:example/other.git
[submodule "opaque"]
path = opaque
url = git@private.example.com:closed/thing.git
[submodule "cgit-host"]
path = cgit-host
url = https://git.kernel.org/pub/scm/git/git.git
[submodule "http-url"]
path = http-url
url = http://example.com/mirrors/subtarget.git
[submodule "git-url"]
path = git-url
url = git://example.com/subtarget.git
[submodule "ssh-url"]
path = ssh-url
url = ssh://git@example.com/srv/subtarget.git
[submodule "file-url"]
path = file-url
url = file:///srv/git/subtarget.git
[submodule "near-miss"]
path = near-miss
url = https://example.com/xsubtarget.git
[submodule "gitlab"]
path = gitlab
url = https://gitlab.com/group/project.git
[submodule "bitbucket"]
path = bitbucket
url = git@bitbucket.org:team/repo.git
[submodule "deps/lib"]
path = deps/lib
url = ../subtarget.git
EOF
git add .gitmodules &&
git commit -m submodules &&
sed "s|git@example.com:mirrors/subtarget.git|https://example.org/moved.git|" .gitmodules >moved &&
mv moved .gitmodules &&
git add .gitmodules &&
git commit -m "move local-ssh"
) &&
cgitrc_repo subrc subparent enable-gitmodules-links=1 &&
echo "repo.url=subtarget" >>subrc &&
echo "repo.path=$PWD/repos/subtarget/.git" >>subrc
'
test_expect_success 'an ssh url served here links to the local repo and commit' '
sub=$(git -C repos/subtarget rev-parse HEAD) &&
old=$(git -C repos/subparent rev-parse HEAD~1) &&
cgit_ok subrc "url=subparent/tree/&id=$old" >tmp &&
grep "local-ssh @ " tmp
'
test_expect_success 'the links follow the .gitmodules of the shown revision' '
sub=$(git -C repos/subtarget rev-parse HEAD) &&
cgit_ok subrc "url=subparent/tree/" >tmp &&
grep "local-ssh @ " tmp
'
test_expect_success 'a relative url resolves against this repository' '
sub=$(git -C repos/subtarget rev-parse HEAD) &&
cgit_ok subrc "url=subparent/tree/" >tmp &&
grep "sibling" tmp
'
test_expect_success 'every scheme that names a repository served here links to it' '
sub=$(git -C repos/subtarget rev-parse HEAD) &&
cgit_ok subrc "url=subparent/tree/" >tmp &&
for name in http-url git-url ssh-url file-url
do
grep "$name @ tmp &&
grep "near-miss @ " tmp
'
test_expect_success 'a web url is linked as it is' '
cgit_ok subrc "url=subparent/tree/" >tmp &&
grep "href=.https://github.com/example/project.git.>forge-https" tmp
'
test_expect_success 'a known forge hash links to its commit page' '
sub=$(git -C repos/subtarget rev-parse HEAD) &&
cgit_ok subrc "url=subparent/tree/" >tmp &&
grep "href=.https://github.com/example/project/commit/$sub." tmp &&
grep "href=.https://gitlab.com/group/project/-/commit/$sub." tmp
'
test_expect_success 'an ssh url to a known forge is rewritten' '
sub=$(git -C repos/subtarget rev-parse HEAD) &&
cgit_ok subrc "url=subparent/tree/" >tmp &&
grep "href=.https://github.com/example/other.>forge-ssh" tmp &&
grep "href=.https://github.com/example/other/commit/$sub." tmp &&
grep "href=.https://bitbucket.org/team/repo.>bitbucket @ tmp &&
grep "cgit-host" tmp &&
grep "href=.https://git.kernel.org/pub/scm/git/git.git/commit/?id=$sub." tmp
'
test_expect_success 'an unresolvable url stays unlinked with a tooltip' '
sub=$(git -C repos/subtarget rev-parse HEAD) &&
cgit_ok subrc "url=subparent/tree/" >tmp &&
grep "opaque @ " tmp
'
# The row names the entry alone, while .gitmodules is looked up by the full
# path.
test_expect_success 'a submodule below the top level is found by its path' '
sub=$(git -C repos/subtarget rev-parse HEAD) &&
cgit_ok subrc "url=subparent/tree/deps" >tmp &&
grep "lib" tmp
'
test_expect_success 'a submodule path is answered with its link' '
sub=$(git -C repos/subtarget rev-parse HEAD) &&
cgit_rc subrc "url=subparent/tree/sibling" >tmp &&
grep "^Status: 404" tmp &&
grep "
This path is a submodule: sibling" tmp
'
# A template is the site saying where its submodules live, so it wins over
# what .gitmodules would give, and a template for one path wins over both.
test_expect_success 'the module-link templates win over .gitmodules' '
sub=$(git -C repos/subtarget rev-parse HEAD) &&
cgitrc_repo modrc subparent enable-gitmodules-links=1 "module-link=/mods/%s/%s" \
"repo.module-link.sibling=/pinned/%s" &&
cgit_ok modrc "url=subparent/tree/" >tmp &&
grep "local-ssh" tmp &&
grep "sibling" tmp &&
! grep "subtarget/tree" tmp
'
# A template takes the path as the tree names it, so a space or a byte past
# ASCII in a path has to be percent-encoded before an href can carry it.
test_expect_success 'a module-link template percent-encodes the path' '
sub=$(git -C repos/subtarget rev-parse HEAD) &&
git init -q repos/oddsub &&
(
cd repos/oddsub &&
git update-index --add --cacheinfo "160000,$sub,my lib" &&
git update-index --add --cacheinfo "160000,$sub,$(printf "caf\303\251")" &&
git commit -q -m "odd submodule paths"
) &&
cgitrc_repo oddrc oddsub "module-link=/mods/%s/%s" &&
cgit_ok oddrc "url=oddsub/tree/" >tmp &&
grep "my lib" tmp &&
grep "caf" tmp &&
! grep "href=./mods/my lib/" tmp
'
test_expect_success 'the links stay off without the flag' '
cgitrc_repo suboffrc subparent &&
cgit_ok suboffrc "url=subparent/tree/" >tmp &&
! grep "subtarget/tree" tmp &&
grep "class=.ls-mod.>local-ssh" tmp
'
test_done