cookutils view cooker @ rev 87

Fix packge status (again)
author Christophe Lincoln <pankso@slitaz.org>
date Sun May 08 03:20:33 2011 +0200 (2011-05-08)
parents 5d21241ca811
children 747bd9aaeb63
line source
1 #!/bin/sh
2 #
3 # SliTaz Build Bot. The Cooker is a tool to automate and test SliTaz package
4 # building. Please read the Cookbook documentation for more information
5 # and discuss with the AUTHORS before adding anything here. PS: no translations
6 # here since it's not an end user tool and it's not useful, all devs should
7 # at least understand basic English.
8 #
10 [ -f "/etc/slitaz/cook.conf" ] && . /etc/slitaz/cook.conf
11 [ -f "cook.conf" ] && . ./cook.conf
13 # Set pkg name and use same wok as cook.
14 pkg="$2"
15 wok="$WOK"
16 flavors="$SLITAZ/flavors"
18 # Cooker DB files.
19 activity="$CACHE/activity"
20 commits="$CACHE/commits"
21 cooklist="$CACHE/cooklist"
22 cookorder="$CACHE/cookorder"
23 command="$CACHE/command"
24 blocked="$CACHE/blocked"
25 broken="$CACHE/broken"
26 cooknotes="$CACHE/cooknotes"
28 # PID file.
29 pidfile='/var/run/cooker.pid'
31 #
32 # Functions
33 #
35 usage() {
36 cat << EOT
38 Usage: cooker [command] [pkg|list|note]
40 Options:
41 usage|-u Display this short usage.
42 setup|-s Setup the Cooker environment.
43 note|-n Add a note to the cooknotes.
44 notes|-ns Display all the cooknotes.
45 block|-b Block a package so cook will skip it.
46 unblock|-ub Unblock a blocked package.
47 pkg|-p Same as 'cook pkg' but with cooker log.
48 flavor|-f Cook all packages of a flavor.
49 list|-l Cook all packages in the given list.
50 cat|-c Cook all packages of a category.
51 rev|-r Cook packages of a specific revision.
52 all|-a Find and cook all unbuilt packages.
54 EOT
55 exit 0
56 }
58 separator() {
59 echo "================================================================================"
60 }
62 # Lograte activity.
63 [ -s "$activity" ] && tail -n 60 $activity > /tmp/tail && \
64 mv -f /tmp/tail $activity
66 # Log activities, we want first letter capitalized.
67 log() {
68 grep ^[A-Z] | \
69 sed s"#^[A-Z]\([^']*\)#$(date '+%Y-%m-%d %H:%M') : \0#" >> $activity
70 }
72 # Some messages occur in activity but log verbose output when checking for commits
73 # into a log file.
74 log_commits() {
75 sed '/^.\//'d | sed '/^.hg/'d | tee -a $LOGS/commits.log
76 }
78 # Log broken packages.
79 broken() {
80 if ! grep -q "^$pkg$" $broken; then
81 echo "$pkg" >> $broken
82 fi
83 }
85 # Clean up before exit when check and cook commits finish.
86 clean_exit() {
87 rm -f $command && touch $command
88 rm -f $pidfile
89 }
91 # Summary for commits.
92 commits_summary() {
93 msg="from revision $cur to $new"
94 [ "$new" == "$cur" ] && msg="revision $new"
95 echo "Will cook $msg"
96 separator
97 echo -e "\nSummary for commits"
98 separator
99 echo "Hg wok revision : $cur"
100 echo "Pulled revision : $new"
101 echo "Check date : $(date '+%Y-%m-%d %H:%M:%S')"
102 }
104 # Scan packages build deps and fill up cookorder list.
105 cook_order_scan() {
106 touch $cooklist $cookorder
107 for pkg in $(cat $cooklist)
108 do
109 unset BUILD_DEPENDS
110 . $wok/$pkg/receipt
111 # The :: is for web interface color.
112 [ "$BUILD_DEPENDS" ] && echo "$pkg :: $BUILD_DEPENDS"
113 for dep in $BUILD_DEPENDS
114 do
115 if grep -q "^$dep$" $cooklist; then
116 if ! grep -q "^$dep$" $cookorder; then
118 echo "$dep" >> $cookorder
119 fi
120 fi
121 done
122 done
124 # Append unordered packages to cookorder.
125 for pkg in $(cat $cooklist)
126 do
127 if ! grep -q "^$pkg$" $cookorder; then
128 echo "$pkg" >> $cookorder
129 fi
130 done
131 }
133 # Scan and rescan until the cooklist is ordered then handle WANTED.
134 cook_order() {
135 time=$(date +%s)
136 scan=0
138 # Keep an original cooklist so we do a diff when ordering is finished.
139 cp -f $cooklist $cooklist.0
140 echo -e "\nInitial Cooker order scan"
141 separator
142 cook_order_scan
144 # Diff between the cooklist and new ordered list ? So copy the last
145 # cookorder to cooklist and rescan it.
146 while /bin/true
147 do
148 diff $cooklist $cookorder > $cookorder.diff
149 if [ -s "$cookorder.diff" ]; then
150 scan=$(($scan + 1))
151 echo -e "\nDiff scan: $scan"
152 separator
153 mv -f $cookorder $cooklist
154 cook_order_scan
155 else
156 break
157 fi
158 done
160 # Keep a diff between submited cooklist and the ordered.
161 diff $cooklist.0 $cooklist > $cooklist.diff
162 rm -f $cookorder $cookorder.diff $cooklist.0
164 # Scan is finished: append pkg to WANTED
165 echo -e "\nHandle WANTED package"
166 separator
167 for pkg in $(cat $cooklist)
168 do
169 unset WANTED
170 . $wok/$pkg/receipt
171 if [ "$WANTED" ]; then
172 echo "$pkg :: $WANTED"
173 sed -i -e "/^$pkg$/"d \
174 -e "/^$WANTED$/ a $pkg" $cooklist
175 fi
176 done
178 # Show ordered cooklist
179 echo -e "\nCooklist order"
180 separator
181 cat $cooklist
182 separator
183 time=$(($(date +%s) - $time))
184 pkgs=$(cat $cooklist | wc -l)
185 echo -e "\nSummary for cookorder"
186 separator
187 cat << EOT
188 Ordered packages : $pkgs
189 Scans executed : $scan
190 Scan duration : ${time}s
191 EOT
192 separator
193 }
195 # Remove blocked (faster this way than grepping before).
196 strip_blocked() {
197 for pkg in $(cat $blocked)
198 do
199 sed -i /^${pkg}$/d $cooklist
200 done && sed -i /^$/d $cooklist
201 }
203 # Use in default mode and with all cmd.
204 cook_commits() {
205 if [ -s "$commits" ]; then
206 for pkg in $(cat $commits)
207 do
208 echo "cook:$pkg" > $command
209 cook $pkg || broken
210 sed -i /^${pkg}$/d $commits
211 done
212 fi
213 }
215 # Cook all packages in a cooklist.
216 cook_list() {
217 for pkg in $(cat $cooklist)
218 do
219 cook $pkg || broken
220 sed -i /^${pkg}$/d $cooklist
221 done
222 }
224 #
225 # Commands
226 #
227 case "$1" in
228 usage|help|-u|-h)
229 usage ;;
230 setup|-s)
231 # Setup the Cooker environment.
232 echo -e "\nSetting up the Cooker"
233 echo "Cooker setup using: $SLITAZ" | log
234 separator
235 for pkg in $SETUP_PKGS mercurial rsync
236 do
237 [ ! -d "$INSTALLED/$pkg" ] && tazpkg get-install $pkg
238 done
239 mkdir -p $SLITAZ && cd $SLITAZ
240 [ -d "${wok}-hg" ] && echo -e "Hg wok already exists.\n" && exit 1
241 [ -d "$wok" ] && echo -e "Build wok already exists.\n" && exit 1
243 # Directories and files
244 echo "mkdir's and touch files in: $SLITAZ"
245 mkdir -p $PKGS $LOGS $CACHE $SRC
246 for f in $activity $blocked $broken $commits $cooklist $command
247 do
248 touch $f
249 done
250 hg clone $WOK_URL ${wok}-hg || exit 1
251 [ -d "$flavors" ] || hg clone $FLAVORS_URL flavors
252 cp -a ${wok}-hg $wok
253 separator && echo "" ;;
254 note|-n)
255 # Blocked a pkg and want others to know why ? Post a note!
256 note="$2"
257 date=$(date "+%Y-%m-%d %H:%M")
258 [ "$note" ] && echo "$date : $note" >> $cooknotes ;;
259 notes|-ns)
260 # View cooknotes.
261 echo -e "\nCooknotes"
262 separator
263 cat $cooknotes
264 separator && echo "" ;;
265 block|-b)
266 # Block a package.
267 [ "$pkg" ] && cook $pkg --block ;;
268 unblock|-ub)
269 # Unblock a package.
270 [ "$pkg" ] && cook $pkg --unblock ;;
271 reverse|-r)
272 # Cook all reverse dependencies for a package. This command lets us
273 # control the Cooker manually for commits that will cook a lot of packages.
274 #
275 # Use hg commit ? Ex: hg commit -m "Message bla bla | cooker:reverse"
276 #
277 [ ! -d "$wok/$pkg" ] && echo -e "\nNo package $2 found.\n" && exit 0
278 rm -f $cooklist && touch $cooklist && cd $wok
279 echo -e "\nReverse cooklist for: $pkg"
280 separator && cd $wok
281 for rev in *
282 do
283 unset DEPENDS BUILD_DEPENDS && . $wok/$rev/receipt
284 if echo "$DEPENDS $BUILD_DEPENDS" | fgrep -q $pkg; then
285 echo "$rev" | tee -a $cooklist
286 fi
287 done && separator
288 echo -e "Reverse dependencies found: $(cat $cooklist | wc -l)\n"
289 strip_blocked
290 cook_order | tee $LOGS/cookorder.log
291 cook_list ;;
292 pkg|-p)
293 # Same as 'cook pkg' but with log for web interface.
294 cook $pkg || broken
295 clean_exit ;;
296 cat|-c)
297 # Cook all packages of a category.
298 cat="$2"
299 rm -f $cooklist && touch $cooklist && cd $wok
300 for pkg in *
301 do
302 unset CATEGORY && . $pkg/receipt
303 [ "$CATEGORY" == "$cat" ] && echo $pkg >> $cooklist
304 done
305 strip_blocked
306 cook_order | tee $LOGS/cookorder.log
307 cook_list ;;
308 flavor|-f)
309 # Cook all packages of a flavor.
310 name="$2"
311 [ ! -d "$flavors/$name" ] && \
312 echo -e "\nSpecified flavor does not exist: $name\n" && exit 1
313 [ -d "$flavors/.hg" ] && cd $flavors && hg pull -u
314 list=$flavors/$name/packages.list
315 cp -a $list $cooklist
316 strip_blocked
317 cook_order | tee $LOGS/cookorder.log
318 cook_list ;;
319 list|-l)
320 # Cook a list of packages given in argument.
321 list="$2"
322 [ ! -f "$list" ] && \
323 echo -e "\nSpecified list does not exist: $list\n" && exit 1
324 cp -a $list $cooklist
325 strip_blocked
326 cook_order | tee $LOGS/cookorder.log ;;
327 rev|-r)
328 # Cook or recook a specific Hg revision.
329 rev="$2"
330 [ "$rev" ] || exit 0
331 cd $wok
332 rm -f $cooklist && touch $cooklist
333 for pkg in $(hg log --rev=$rev --template "{files}")
334 do
335 echo "$pkg" | cut -d "/" -f 1 >> $cooklist
336 done
337 strip_blocked
338 cook_order | tee $LOGS/cookorder.log
339 cook_list ;;
340 all|-a)
341 # Try to build all unbuilt packages except blocked's.
342 echo "cooker:all" > $command
343 rm -f $cooklist && touch $cooklist
344 echo "" && cd $wok
345 echo "Cooker cooklist"
346 separator
348 # Find all unbuilt packages.
349 echo "Searching for all unbuilt packages" | log
350 for pkg in *
351 do
352 . $pkg/receipt
353 [ ! -f "$PKGS/$PACKAGE-${VERSION}${EXTRAVERSION}.tazpkg" ] && \
354 echo $pkg >> $cooklist
355 done
357 strip_blocked
358 echo "Packages to cook: $(cat $cooklist | wc -l)" | log
359 cook_order | tee $LOGS/cookorder.log
360 cook_list ;;
361 *)
362 # Default is to cook all commits if not yet running.
363 [ "$1" ] && usage
364 cooklist=$CACHE/commits
365 if [ -f "$pidfile" ]; then
366 pid=$(cat /var/run/cooker.pid)
367 gettext -e "\nStill cooking latest commits with pid:"
368 echo -e " $pid\n" && exit 0
369 fi
371 # Start and get a PID file.
372 rm -f $LOGS/commits.log
373 echo ""
374 echo "Checking for commits" | log_commits
375 separator | tee -a $LOGS/commits.log
376 echo $$ > $pidfile
377 echo "Cooker PID : $$" | log_commits
378 echo "Cooker date : $(date '+%Y-%m-%d %H:%M:%S')" | log_commits
380 # Get revisions. Here we have 2 echo since we want msg on screen,
381 # in commits log and activity DB without space before :
382 cd $wok || exit 1
383 cur=$(hg head --template '{rev}\n')
384 echo "Updating wok : ${wok}-hg (rev $cur)" | log_commits
385 echo "Updating wok: ${wok}-hg" | log
386 echo "hg:pull" > $command
387 cd ${wok}-hg && hg pull -u | log_commits
388 new=$(hg head --template '{rev}\n')
390 # Sync build wok with rsync so we don't take care about removing old
391 # files as before.
392 if [ "$new" -gt "$cur" ]; then
393 echo "Changes found from: $cur to $new" | log
394 echo "Syncing build wok with Hg wok..." | log_commits
395 rsync -r -t -c -l -u -v -D -E ${wok}-hg/ $wok/ | \
396 sed '/^$/'d | log_commits
397 else
398 echo "No revision changes: $cur vs $new" | log
399 separator | log_commits
400 clean_exit && echo "" && exit 0
401 fi
403 # Get and display modifications.
404 cd ${wok}-hg
405 cur=$(($cur + 1))
406 commits_summary | log_commits
407 rm -f $commits.tmp && touch $commits.tmp
408 for rev in $(seq $cur $new)
409 do
410 for file in $(hg log --rev=$rev --template "{files}")
411 do
412 pkg=$(echo $file | cut -d "/" -f 1)
413 desc=$(hg log --rev=$rev --template "{desc}" $file)
414 echo "Commited : $pkg - $desc" | log_commits
415 echo $pkg >> $commits.tmp
416 done
417 done
419 # Keep previous commit and discard duplicate lines
420 pkgs=$(cat $commits | wc -l)
421 cat $commits $commits.tmp | sed /"^$"/d > $commits.new
422 uniq $commits.new > $commits && rm $commits.*
423 echo "Packages to cook: $pkgs" | log_commits
424 echo "Packages to cook: $pkgs" | log
425 separator | log_commits
426 echo ""
427 strip_blocked
428 cook_order | tee $LOGS/cookorder.log
429 cook_commits
430 clean_exit ;;
431 esac
433 exit 0