What's cooking (2021/06 #06)
[git] / cycle-run
1 #!/bin/sh
2
3 : ${RANGE:=origin/master..origin/seen} ${J:=j32} ${OKNG:="(OK|NG)"}
4
5 test_it () {
6         type=$1 commit=$2 subject=$3
7         log=".Cycle/log.$commit"
8         rm -f "$log"
9         git ls-files -x Meta -x .Cycle -o -z | xargs -r -0 rm -rf
10
11         (
12                 echo "*** log for $subject ***" &&
13                 case "$type" in
14                 C)
15                         # Single parent commit on a topic
16                         Meta/Make -$J &&
17                         Meta/Make -$J -- SPARSE_FLAGS=-Wsparse-error sparse
18                         ;;
19                 M)
20                         # Merges on the first-parent chain on seen
21                         Meta/Make -$J -- SPARSE_FLAGS=-Wsparse-error sparse &&
22                         Meta/Make -$J -- test
23                         ;;
24                 T)
25                         # Commit at the tip of a topic
26                         Meta/Make -$J SANITIZE=address,undefined -- test &&
27                         Meta/Make -$J -- doc
28                         ;;
29                 esac
30
31                 status=$?
32
33                 # Does 'distclean' clean them up properly?
34                 Meta/Make -- $D distclean >/dev/null
35                 case $(git ls-files -x Meta -x .Cycle -o | wc -l) in
36                 0) exit "$status" ;;
37                 *) git ls-files -x Meta -x .Cycle -o
38                    exit 1 ;;
39                 esac
40         ) >"$log" 2>&1
41         case $? in
42         0)      rm -f "$log" ;;
43         *)      return 1 ;;
44         esac
45 }
46
47 tested () {
48         # sign=$1 commit=$2
49         egrep "^$OKNG $1($2|$(git rev-parse "$2^{tree}"))" .Cycle/log >/dev/null
50 }
51
52 test_them () {
53         while read merge parent sides
54         do
55                 case "$parent" in
56                 ?*)
57                         tested M $merge && continue
58                         echo "TEST M $merge"
59
60                         for tip in $sides
61                         do
62                                 git rev-parse --verify --quiet "$tip" || continue
63                                 tested T $tip && continue
64                                 echo "TEST $tip $merge"
65                         done
66                         ;;
67                 '')
68                         commit=$merge
69                         git rev-parse --verify --quiet "$commit" || continue
70                         tested C $commit && continue
71                         echo "TEST C $commit"
72                 esac
73         done |
74         sed -n -e 's/^TEST //p' >.Cycle/plan
75
76         count=$(wc -l <.Cycle/plan)
77         case $count in 0) return ;; esac
78
79         total=$count
80         echo TEST $count ON $(date) >>.Cycle/log
81         while read tip merge
82         do
83                 case "$tip" in
84                 M)
85                         type=M
86                         commit=$merge
87                         subject=$(git show -s --format="%s" "$commit") ;;
88                 C)
89                         type=C
90                         commit=$merge
91                         subject=$(git show -s --format="%s" "$commit") ;;
92                 *)
93                         type=T
94                         commit=$tip
95                         subject=$(
96                                 git show -s --format="%s" "$merge" |
97                                 sed -e 's/^Merge branch '\''\(.*\)'\'' into .*/\1/'
98                         ) ;;
99                 esac
100
101                 echo >&2 -n "$count/$total ?? $subject\r"
102                 if test_it $type $commit "$subject"
103                 then
104                         OK=OK
105                 else
106                         OK=NG
107                 fi
108                 echo "$OK $type$commit $count" >>.Cycle/log
109                 echo "$OK $type$(git rev-parse $commit^{tree}) $count" >>.Cycle/log
110                 echo >&2 "$count/$total $OK $subject"
111                 count=$(( $count - 1 ))
112         done <.Cycle/plan
113 }
114
115 : >>.Cycle/log
116 git reflog expire --expire=now --expire-unreachable=now --all
117 git gc
118
119 for l in .Cycle/log.[0-9a-f]*
120 do
121         x=${l##*.}
122         git rev-parse --verify "$x" >/dev/null 2>&1 || rm -f "$l"
123 done
124
125 git fetch
126 (
127         git rev-list --no-merges $RANGE
128         git rev-list --first-parent --parents $RANGE
129 ) | test_them