cogito: understand permissions written as "100755"
[cogito.git] / contrib / neutral.sh
blob7d944f75d1cbd8e1feadbd175ff1f6815e6bb24c
1 #!/usr/bin/env bash
3 # This is experiment on http://revctrl.org/NeutralInterface, implementing
4 # the interface.
6 die() {
7 echo "$@" >&2
8 exit 1
11 # Take a field name as an argument and check in the $interesting[] array
12 # whether we should output it.
13 interesting() {
14 [ "${interesting[0]}" = '*' ] && return 0
15 for field in "${interesting[@]}"; do
16 [ "$field" = "$1" ] && return 0
17 done
18 return 1
22 if [ ! "$1" ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
23 die http://revctrl.org/NeutralInterface
26 interesting=('*')
27 if [ "$1" = "-s" ]; then
28 shift; interesting=(${1//,/ }); shift
31 cmd="$1"; shift; args=("$@");
32 interactive=
33 [ "$cmd" = "-i" ] && interactive=1
35 while [ "$cmd" ]; do
36 if [ "$cmd" = "-i" ]; then
37 : # nothing
39 elif [ "$cmd" = "version" ]; then
40 interesting "version" && echo "version:1:0"
42 elif [ "$cmd" = "identify" ]; then
43 interesting "type" && echo "type:3:git"
45 elif [ "$cmd" = "changeset" ]; then
46 [ "${args[0]}" ] || die "missing changeset id"
47 commit="$(git-rev-parse --verify "${args[0]}")" || die "bad changeset id"
48 interesting "identifier" && echo "identifier:40:$commit"
50 interesting "parent" &&
51 for parent in $(git-rev-parse --verify "$commit"^); do
52 echo "parent:40:$parent"
53 done
55 interesting "tag" &&
56 grep -r -l "$commit" ${GIT_DIR:-.git}/refs/tags |
57 while IFS=$'\n' read tag; do
58 tag="${tag##*/}"
59 echo "tag:${#tag}:$tag"
60 done
62 # FIXME: doesn't handle filenames containing newlines
63 interesting "file" &&
64 echo $commit $(git-rev-parse --verify "$commit"^) |
65 git-diff-tree -r -m --stdin | grep ^: | cut -f 2- |
66 while IFS=$'\n' read file; do
67 echo "file:${#file}:$file"
68 done
70 if interesting "user" || interesting "date"; then
71 author="$(git-cat-file commit "$commit" | sed -n 's/^author //p;/^$/q')"
73 if interesting "user"; then
74 user="$(echo "$author" | sed 's/\([^<]* <[^>]*>\).*/\1/')"
75 echo user:${#user}:"$user"
78 if interesting "date"; then
79 date="$(echo "$author" | sed 's/[^<]* <[^>]*> \(.*\)/\1/')"
80 echo date:${#date}:"$date"
84 if interesting "description"; then
85 desc="$(git-cat-file commit "$commit" | sed -n '/^$/{:a n;p;b a}')"
86 echo description:${#desc}:"$desc"
89 else
90 die "unknown command"
93 cmd=
94 if [ "$interactive" ]; then
95 echo # terminate output
96 read cmd
97 interesting=('*')
98 cmdname="${cmd%%+*}"
99 if [ "$cmdname" != "$cmd" ]; then
100 fields="${cmd#*+}"
101 interesting=(${fields//,/ })
102 cmd="$cmdname"
105 args=()
106 while true; do
107 # do with bash, I guess.
108 IFS=$'\n' read arg
109 [ "$arg" ] || break
110 arglen="${arg%%:*}"
111 argval="${arg#*:}"
112 while [ "${#argval}" -lt "$arglen" ]; do
113 IFS=$'\n' read argvalmore
114 argval="$argval
115 $argvalmore"
116 done
117 [ "${#argval}" -gt "$arglen" ] &&
118 die "announced value length ($arglen) doesn't match what I really snapped (${#argval})"
119 args[${#args[@]}]=${arg#*:}
120 done
122 done