2018-10-31 03:33:47 -04:00
|
|
|
#!/bin/sh
|
|
|
|
|
. ./do
|
|
|
|
|
|
|
|
|
|
set -e
|
|
|
|
|
|
|
|
|
|
NAME=$(basename "$0")
|
|
|
|
|
TESTNUM=0
|
|
|
|
|
SECT=root
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SECTION()
|
|
|
|
|
{
|
|
|
|
|
SECT=$1
|
|
|
|
|
TESTNUM=0
|
|
|
|
|
printf "\nTesting \"$1\" in $0:\n"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
no_nl()
|
|
|
|
|
{
|
|
|
|
|
echo "$1" | {
|
|
|
|
|
out=
|
|
|
|
|
while read -r line; do
|
|
|
|
|
out="$out$line "
|
|
|
|
|
done
|
|
|
|
|
printf "%s" "${out% }"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
check_s()
|
|
|
|
|
{
|
|
|
|
|
local want="$1" got="$2" cmd="$3"
|
|
|
|
|
want_s=$(no_nl "$want")
|
|
|
|
|
got_s=$(no_nl "$got")
|
|
|
|
|
[ -z "$cmd" ] && cmd=$got
|
|
|
|
|
TESTNUM=$((TESTNUM + 1))
|
|
|
|
|
if [ "$want" != "$got" ]; then
|
|
|
|
|
printf "\n<<< expected:\n%s\n=== got:\n%s\n>>>\n" "$want" "$got"
|
|
|
|
|
printf "! %s:%d '%.40s' = %s FAILED\n" "$SECT" "$TESTNUM" "$want_s" "$cmd"
|
|
|
|
|
exit 1
|
|
|
|
|
else
|
|
|
|
|
printf "! %s:%d '%.40s' = %s ok\n" "$SECT" "$TESTNUM" "$want_s" "$cmd"
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
check()
|
|
|
|
|
{
|
|
|
|
|
local want="$1" got= rv=
|
|
|
|
|
shift
|
|
|
|
|
rv=0
|
|
|
|
|
got=$("$@") || rv=$?
|
|
|
|
|
if [ "$rv" -ne 0 ]; then
|
|
|
|
|
check_s "<returned 0>" "<returned $rv>"
|
|
|
|
|
else
|
|
|
|
|
check_s "$want" "$got" "$*"
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
retval()
|
|
|
|
|
{
|
|
|
|
|
set +e
|
|
|
|
|
"$@" >&2
|
|
|
|
|
local rv=$?
|
|
|
|
|
set -e
|
|
|
|
|
echo "$rv"
|
|
|
|
|
return 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SECTION _starts_ends_with
|
|
|
|
|
check "0" retval true
|
|
|
|
|
check "1" retval false
|
|
|
|
|
check "0" retval _startswith "x.test" "x."
|
|
|
|
|
check "1" retval _startswith "x.test" "y."
|
|
|
|
|
check "1" retval _startswith "" " "
|
|
|
|
|
check "1" retval _startswith "x.test" "x*"
|
|
|
|
|
check "1" retval _startswith "do.test" "do*"
|
|
|
|
|
|
|
|
|
|
check "0" retval _endswith "x.test" ".test"
|
|
|
|
|
check "1" retval _endswith "x.test" ".best"
|
|
|
|
|
check "1" retval _endswith "" " "
|
|
|
|
|
check "1" retval _endswith "x.test" "*.test"
|
|
|
|
|
check "1" retval _endswith "do.test" "*.test"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SECTION _dirsplit
|
|
|
|
|
_dirsplit "/a/b/c"
|
|
|
|
|
check_s "/a/b/" "$_dirsplit_dir"
|
|
|
|
|
check_s "c" "$_dirsplit_base"
|
|
|
|
|
|
|
|
|
|
_dirsplit "/a/b/c/"
|
|
|
|
|
check_s "/a/b/c/" "$_dirsplit_dir"
|
|
|
|
|
check_s "" "$_dirsplit_base"
|
|
|
|
|
|
|
|
|
|
_dirsplit "/"
|
|
|
|
|
check_s "/" "$_dirsplit_dir"
|
|
|
|
|
check_s "" "$_dirsplit_base"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SECTION _relpath
|
Use mkstemp() to create the stdout temp file, and simplify $3 path.
Previously, we'd try to put the stdout temp file in the same dir as the
target, if that dir exists. Otherwise we'd walk up the directory tree
looking for a good place. But this would go wrong if the directory we
chose got *deleted* during the run of the .do file.
Instead, we switch to an entirely new design: we use mkstemp() to
generate a temp file in the standard temp file location (probably
/tmp), then open it and immediately delete it, so the .do file can't
cause any unexpected behaviour. After the .do file exits, we use our
still-open fd to the stdout file to read the content back out.
In the old implementation, we also put the $3 in the "adjusted"
location that depended whether the target dir already existed, just for
consistency. But that was never necessary: we didn't create the $3
file, and if the .do script wants to write to $3, it should create the
target dir first anyway. So change it to *always* use a $3 temp
filename in the target dir, which is much simpler and so has fewer edge
cases.
Add t/202-del/deltest4 with some tests for all these edge cases.
Reported-by: Jeff Stearns <jeff.stearns@gmail.com>
2018-12-12 03:37:44 +00:00
|
|
|
x=$PWD/x
|
|
|
|
|
check "a/b/c" _relpath "$x/a/b/c" "$x"
|
|
|
|
|
check "../a/b/c" _relpath "$x/../a/b/c" "$x"
|
|
|
|
|
check "" _relpath "$x" "$x"
|
|
|
|
|
check "a/b/c" _relpath a/b/c "/"
|
|
|
|
|
check "a/b/c" _relpath /a/b/c "/"
|
|
|
|
|
check "" _relpath / "/"
|
|
|
|
|
check "../lib" _relpath /usr/lib "/usr/bin"
|
|
|
|
|
check "../lib/" _relpath /usr/lib/ "/usr/bin"
|
|
|
|
|
check "../.." _relpath / "/usr/bin"
|
|
|
|
|
check ".." _relpath .. "$PWD/fakedir"
|
|
|
|
|
check "../" _relpath ../ "$PWD/fakedir"
|
|
|
|
|
check "../fakedir" _relpath ../fakedir "$PWD/fakedir"
|
2018-10-31 03:33:47 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
SECTION _normpath
|
Use mkstemp() to create the stdout temp file, and simplify $3 path.
Previously, we'd try to put the stdout temp file in the same dir as the
target, if that dir exists. Otherwise we'd walk up the directory tree
looking for a good place. But this would go wrong if the directory we
chose got *deleted* during the run of the .do file.
Instead, we switch to an entirely new design: we use mkstemp() to
generate a temp file in the standard temp file location (probably
/tmp), then open it and immediately delete it, so the .do file can't
cause any unexpected behaviour. After the .do file exits, we use our
still-open fd to the stdout file to read the content back out.
In the old implementation, we also put the $3 in the "adjusted"
location that depended whether the target dir already existed, just for
consistency. But that was never necessary: we didn't create the $3
file, and if the .do script wants to write to $3, it should create the
target dir first anyway. So change it to *always* use a $3 temp
filename in the target dir, which is much simpler and so has fewer edge
cases.
Add t/202-del/deltest4 with some tests for all these edge cases.
Reported-by: Jeff Stearns <jeff.stearns@gmail.com>
2018-12-12 03:37:44 +00:00
|
|
|
check "/usr/lib" _normpath /usr/../usr/bin/../lib "$x"
|
|
|
|
|
check "/" _normpath /a/b/c/../../.. "$x"
|
|
|
|
|
check "/" _normpath / "$x"
|
|
|
|
|
check "../a" _normpath ../a "$x"
|
|
|
|
|
check "../a/b" _normpath ../a/b "$x/fakedir"
|
|
|
|
|
check ".." _normpath .. "$x/fakedir"
|
|
|
|
|
check "tuv" _normpath a/b/../../tuv "/"
|
|
|
|
|
check "" _normpath a/b/../.. "/"
|
|
|
|
|
check ".." _normpath ../ "$x"
|
|
|
|
|
check ".." _normpath .. "$x"
|
2018-10-31 03:33:47 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
SECTION _find_dofile
|
|
|
|
|
check "test.do" _find_dofiles test
|
|
|
|
|
check "test.do" _find_dofile test
|
|
|
|
|
|
|
|
|
|
want="x.y.zz.do
|
|
|
|
|
default.y.zz.do
|
|
|
|
|
default.zz.do"
|
|
|
|
|
check "$want" _find_dofiles x.y.zz
|
|
|
|
|
|
|
|
|
|
want="x.y.zz.do
|
|
|
|
|
default.y.zz.do
|
|
|
|
|
default.zz.do
|
|
|
|
|
default.do
|
|
|
|
|
../default.y.zz.do
|
|
|
|
|
../default.zz.do"
|
|
|
|
|
(cd fakedir && check "$want" _find_dofiles x.y.zz)
|
|
|
|
|
(cd fakedir && check "../default.zz.do" _find_dofile x.y.zz)
|
|
|
|
|
|
|
|
|
|
set +e
|
|
|
|
|
got=$(_find_dofiles x.y.z)
|
|
|
|
|
rv=$?
|
|
|
|
|
set -e
|
|
|
|
|
check_s "1" "$rv"
|
|
|
|
|
top_want="x.y.z.do
|
|
|
|
|
default.y.z.do
|
|
|
|
|
default.z.do
|
|
|
|
|
default.do
|
|
|
|
|
../default.y.z.do
|
|
|
|
|
../default.z.do
|
|
|
|
|
../default.do"
|
|
|
|
|
check_s "$top_want" "$(echo "$got" | head -n 7)" "_find_dofiles x.y.z"
|
|
|
|
|
|
|
|
|
|
exit 0
|