~ecs/tm

2af0fd1fc5d7f1f1a1dfaadd9162fd2ddfef040f — Ember Sawady 3 years ago 339c1b3
insert: handle trees
6 files changed, 65 insertions(+), 16 deletions(-)

M COMMANDS.md
M lib.sh
M tm-cat
M tm-init
M tm-insert
M tm-update-ref
M COMMANDS.md => COMMANDS.md +1 -2
@@ 3,8 3,7 @@
## Plumbing

- `cat <hash>`: read an object
- `insert <path>`: write a blob or tree. Note: will not recursively add
  subdirectories.
- `insert [-t <type>] [<file>|<directory>]`: recursively write a blob or tree
- `update-ref <ref-name> <commit-hash>`: update a ref to point to a
  commit


M lib.sh => lib.sh +15 -2
@@ 1,8 1,8 @@
TM_DIR="${TM_DIR:-.tm}"
export TM_DIR="${TM_DIR:-$PWD/.tm}"
TMPDIR="${TMPDIR:-/tmp}"
TMPDIR="$TMPDIR/tm.$$.$(date)"
mkdir -- "$TMPDIR"
trap "rm -f '$TMPDIR'; exit" INT
trap "rm -rf '$TMPDIR'; exit" INT
trap "rm -rf '$TMPDIR'" EXIT

# Resolve a reference


@@ 36,3 36,16 @@ write() {
	rm -f -- "$tmp"
	printf "%s\n" "$hash"
}

ch() {
	printf "%s\n" "$2" | cut -c"$1"
}

postfix() {
	len="$(printf "%s" "$1" | wc -c)"
	while read -r "line"; do
		linelen="$(printf "%s" "$line" | wc -c)"
		post="$(printf "%s" "$line" | cut -c"$((linelen - len + 1))-$linelen" 2>/dev/null)"
		[ "z$post" = "z$1" ] && printf "%s\n" "$line"
	done
}

M tm-cat => tm-cat +2 -2
@@ 2,7 2,7 @@

if [ $# -ne 1 ]; then
	echo "usage: tm cat <ref>"
	exit
	exit 1
fi
. "$(dirname -- "$0")/lib.sh"
cat "$TM_DIR/objects/$(resolve_ref "$1" || echo "error: invalid ref" >&2 || exit)"
cat "$TM_DIR/objects/$(resolve_ref "$1" || echo "error: invalid ref" >&2 || exit 1)"

M tm-init => tm-init +1 -1
@@ 2,7 2,7 @@

if [ $# -ne 0 ]; then
	echo "usage: tm init"
	exit
	exit 1
fi
. "$(dirname -- "$0")/lib.sh"
mkdir -p -- "$TM_DIR/objects" "$TM_DIR/refs"

M tm-insert => tm-insert +44 -7
@@ 1,12 1,12 @@
#!/bin/sh -eu

usage() {
	echo "usage: tm insert [-t type] [<file>]"
	exit
	echo "usage: tm insert [-t <type>] [<file>|<directory>]"
	exit 1
}

. "$(dirname -- "$0")/lib.sh"
type=blob
type=default

while getopts t: opt; do
	case "$opt" in


@@ 21,11 21,48 @@ done

shift "$((OPTIND - 1))"

if [ $# -gt 1 ]; then
	usage
fi
[ $# -gt 1 ] && usage

[ $# -eq 1 ] && [ -d "$1" ] && [ "z$type" = "zdefault" ] && type=tree
[ "z$type" = "zdefault" ] && type=blob

tmp="$TMPDIR/insert"
printf "%s\n" "$type" >"$tmp"
cat -- $@ >"$tmp"
case "$type" in
blob)
	cat -- $@ >"$tmp"
	;;
tree)
	[ $# -eq 1 ] && cd "$1"
	IFS='
'
	for file in $(ls -A); do
		mode="$(ls -lA | postfix " $file" | cut -f1 -d' ')"
		case "$(ch 1 "$mode")" in
		b|c|l|p)
			printf "error: non-regular file %s\n" "$file"
			exit
		esac
		m=0
		[ "z$(ch 2 "$mode")" = "zr" ] && m="$((m + 400))"
		[ "z$(ch 3 "$mode")" = "zw" ] && m="$((m + 200))"
		[ "z$(ch 4 "$mode")" = "zx" ] && m="$((m + 100))"
		[ "z$(ch 5 "$mode")" = "zr" ] && m="$((m + 40))"
		[ "z$(ch 6 "$mode")" = "zw" ] && m="$((m + 20))"
		[ "z$(ch 7 "$mode")" = "zx" ] && m="$((m + 10))"
		[ "z$(ch 8 "$mode")" = "zr" ] && m="$((m + 4))"
		[ "z$(ch 9 "$mode")" = "zw" ] && m="$((m + 2))"
		[ "z$(ch 10 "$mode")" = "zx" ] && m="$((m + 1))"
		hash="$(tm insert -- "$file")"
		printf "%s %s %s\n" "$m" "$hash" "$file" >>"$tmp"
	done	
	;;
commit)
	echo "TODO: implement this" >&2
	exit 1
	;;
*)
	echo "invalid type" >&2
	exit 1
esac
write <"$tmp"

M tm-update-ref => tm-update-ref +2 -2
@@ 2,7 2,7 @@

if [ $# -ne 2 ]; then
	echo "usage: tm update-ref <refname> <ref>"
	exit
	exit 1
fi
. "$(dirname -- "$0")/lib.sh"
out=""


@@ 14,5 14,5 @@ else
	printf "creating ref %s\n" "$1"
	out="$TM_DIR/refs/$1"
fi
ref="$(resolve_ref "$2" || echo "error: invalid ref" >&2 || exit)"
ref="$(resolve_ref "$2" || echo "error: invalid ref" >&2 || exit 1)"
printf "%s\n" "$ref" >"$out"