1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#!/bin/sh -eu
# ^ for shellcheck
export CDPATH=""
abort() {
printf "%s\n" "$@" >&2
exit 1
}
ch() {
printf "%s\n" "$2" | cut -c"$1"
}
isignored() {
! [ -f "$TM_IGNORE" ] && return 1
IFS='
'
path="$( (
if [ -d "$1" ]; then
cd -- "$1" || exit
printf "%s" "$PWD"
else
cd -- "$(dirname -- "$1")" || exit
printf "%s" "$PWD/$(basename -- "$1")"
fi
))"
len="$( ( cd -- "$TM_WS" && pwd | wc -c) )"
path="$(printf "%s" "$path" | cut -c"$((len + 1))-" 2>/dev/null)"
while IFS= read -r line; do
[ "z$(ch 1 "$line")" = "z#" ] && continue
printf "%s\n" "$path" | grep -Eq "$line" && return 0
done <"$TM_IGNORE"
return 1
}
postfix() {
len="$(printf "%s" "$1" | wc -c)"
while IFS= read -r "line"; do
linelen="$(printf "%s" "$line" | wc -c)"
post="$(printf "%s" "$line" | cut -c"$((linelen - len + 1))-" 2>/dev/null || true)"
[ "z$post" = "z$1" ] && printf "%s\n" "$line"
done
}
write() {
tmp="$TMPDIR/write"
cat >"$tmp"
# TODO: replace this with something POSIX
hash="$(sha512sum -- "$tmp" | cut -f1 -d' ')"
cat "$tmp" >"$TM_DIR/objects/$hash"
rm -f -- "$tmp"
printf "%s\n" "$hash"
}
path="$PWD"
while ! [ -d "$path/.tm" ]; do
path="$path/.."
cd -- "$path"
[ "z$PWD" = "z/" ] && cd - >/dev/null && break
cd - >/dev/null
done
cd -- "$path"
export TM_DIR="${TM_DIR:-$PWD/.tm}"
cd - >/dev/null
export TM_WS="${TM_WS:-$TM_DIR/..}"
export TM_IGNORE="${TM_IGNORE:-$TM_WS/.tmignore}"
TMPDIR="${TMPDIR:-/tmp}"
tmpname=0
while ! mkdir -- "$TMPDIR/tm.$((tmpname))" 2>/dev/null; do
tmpname="$((tmpname+1))"
done
TMPDIR="$TMPDIR/tm.$tmpname"
trap 'rm -rf "$TMPDIR"; exit' INT
trap 'rm -rf "$TMPDIR"' EXIT