wok view tazbb/stuff/tazbb @ rev 6330

Make sure package receipt exists before source in check_commit function. I hope this causes no problems.
author Christopher Rogers <slaxemulator@gmail.com>
date Sat Sep 18 16:45:22 2010 +0000 (2010-09-18)
parents 7f4cba687330
children 40dc53a88848
line source
1 #!/bin/sh
2 # Tazbb - SliTaz Build Bot.
3 # System wide config file: /etc/slitaz/tazbb.conf
4 #
5 # Tazbb is a tool to automate package building, it can be run manually
6 # or via a cron job. On SliTaz build host, tazbb is run in a chroot env.
7 #
8 # (c) 2009 SliTaz GNU/Linux project - GNU gpl v3
9 #
11 # Include config file or exit if no file found.
12 if [ -f "./tazbb.conf" ]; then
13 . ./tazbb.conf
14 elif [ -f "/etc/slitaz/tazbb.conf" ]; then
15 . /etc/slitaz/tazbb.conf
16 else
17 echo -e "\nNo config file found: tazbb.conf...\n" && exit 0
18 fi
19 LOG_SUFFIX=""
20 case "$HG_WOK" in
21 *stable) LOG_SUFFIX="&stable=1";;
22 esac
24 # Tazbb is only for root.
25 if test $(id -u) != 0 ; then
26 echo -e "\nYou must be root to run: `basename $0`.\n" && exit 0
27 fi
29 # Let tazbb finish is work and make sure needed files exist.
30 if [ -f $LOCK_FILE ]; then
31 case $1 in
32 usage|list-*|*block|check-receipt)
33 continue ;;
34 *)
35 echo -e "\nTazbb is already running and locked...\n"
36 exit 0 ;;
37 esac
38 else
39 mkdir -p $DB_DIR $LOG_DIR
40 touch $LOCK_FILE $DB_DIR/blocked
41 fi
43 # Set KERNEL variable
44 if [ -s $BUILD_WOK/linux/receipt ]; then
45 . $BUILD_WOK/linux/receipt
46 KERNEL=$VERSION
47 fi
49 # Get revision
50 cd $HG_WOK
51 NEW_REV=`hg head --template '{rev}\n'`
52 cd - > /dev/null
54 usage()
55 {
56 echo -e "\nSliTaz developers and build host tool\n
57 \033[1mUsage: \033[0m `basename $0` [command] [--option]
58 \033[1mCommands: \033[0m\n
59 usage Print this short usage and command list.
60 list-pkgs List last cooked packages with date.
61 report Run in report mode and dont cook anything [--verbose].
62 cook Cook, install and log a single package build.
63 cook-all Cook all missing, modified or unbuilt packages.
64 cook-commit Cook all packages affected by a commit in the last update.
65 test-pkgs Execute a test suite on all packages [--verbose].
66 [un]block Block or unblock a package to skip or enable building.
67 mail Send mail to package maintainer with tazbbmail.
68 check-depends Verify DEPENDS value with library needs [--verbose].
69 clean-up Remove old packages [--verbose|--dry-run].
70 clean-log Remove all generated build log files.\n"
71 }
73 status()
74 {
75 local CHECK=$?
76 echo -en "\033[70G"
77 if [ $CHECK = 0 ]; then
78 echo "Done"
79 else
80 echo "Failed"
81 fi
82 return $CHECK
83 }
85 top_summary()
86 {
87 cat > $DB_DIR/summary << _EOT_
88 Update : `date`
89 Revision : $NEW_REV (<a href="$HG_URL/log/$NEW_REV">changelog</a>)
90 _EOT_
91 }
93 packages_summary()
94 {
95 if ! grep -q "^Packages" $DB_DIR/summary; then
96 cat >> $DB_DIR/summary << _EOT_
97 Packages : `ls $BUILD_WOK | wc -l` in the wok, `cat $DB_DIR/cooklist | wc -l` to cook, \
98 `cat $DB_DIR/blocked | wc -l` blocked, `cat $DB_DIR/corrupted | wc -l` corrupted
99 _EOT_
100 fi
101 }
103 VERBOSE=""
105 packages_summary_update()
106 {
107 sed -i s/"[0-9]* in the wok"/"`ls $BUILD_WOK | wc -l` in the wok"/ \
108 $DB_DIR/summary
109 sed -i s/"[0-9]* to cook"/"`cat $DB_DIR/cooklist | wc -l` to cook"/ \
110 $DB_DIR/summary
111 sed -i s/"[0-9]* blocked"/"`cat $DB_DIR/blocked | wc -l` blocked"/ \
112 $DB_DIR/summary
113 sed -i s/"[0-9]* corrupted"/"`cat $DB_DIR/corrupted | wc -l` corrupted"/ \
114 $DB_DIR/summary
115 }
117 list_packages()
118 {
119 cd $PACKAGES_REPOSITORY
120 ls -1t *.tazpkg | head -20 | \
121 while read file
122 do
123 echo -n $(stat -c '%y' $PACKAGES_REPOSITORY/$file | cut -d. -f1)
124 echo " $file"
125 done
126 }
128 show_report()
129 {
130 echo "Cooklist"
131 echo "================================================================================"
132 cat $DB_DIR/cooklist && echo ""
133 echo "Packlist"
134 echo "================================================================================"
135 cat $DB_DIR/packlist && echo ""
136 echo "Blocked"
137 echo "================================================================================"
138 cat $DB_DIR/blocked && echo ""
139 echo ""
140 }
142 # URL encoding
143 escape()
144 {
145 echo $1 | sed -e 's/+/%2B/g' -e 's|/|%2F|g' -e 's/:/%3A/g'
146 }
148 update_wok()
149 {
150 local forced
151 forced=""
152 echo ""
153 echo "(updating flavors)" > $DB_DIR/running
154 cd $HG_FLAVORS
155 LAST_REV=`hg head --template '{rev}\n'`
156 hg pull && hg update
157 NEW_REV=`hg head --template '{rev}\n'`
158 if [ "$NEW_REV" != "$LAST_REV" ]; then
159 size=`du -sh $HG_FLAVORS | awk '{ print $1 }'`
160 echo -n "Copying Hg flavors to the build flavors ($size)... "
161 cp -a $HG_FLAVORS/* $BUILD_FLAVORS
162 cp -a $HG_FLAVORS/.hg $BUILD_FLAVORS
163 echo -e "Done\n"
164 forced="yes"
165 fi
166 echo "(updating wok)" > $DB_DIR/running
167 cd $HG_WOK
168 LAST_REV=`hg head --template '{rev}\n'`
169 hg pull && hg update
170 NEW_REV=`hg head --template '{rev}\n'`
171 # Gen a new summary and link last revision for the web interface.
172 echo -e "\nHg wok : $HG_WOK ($NEW_REV)"
173 echo -e "Build wok : $BUILD_WOK ($LAST_REV)\n"
174 top_summary
175 # Copy Hg wok if new revision or exit to stop process since nothing
176 # have change (--forced can be used).
177 if [ "$NEW_REV" != "$LAST_REV" ]; then
178 size=`du -sh $HG_WOK | awk '{ print $1 }'`
179 echo -n "Copying Hg wok to the build wok ($size)... "
180 #rsync -r -n -t $HG_WOK/ $BUILD_WOK/
181 cp -a $HG_WOK/* $BUILD_WOK
182 cp -a $HG_WOK/.hg $BUILD_WOK
183 echo -e "Done\n"
184 else
185 if [ "$1" = "cook-all" ] || [ "$1" = "cook-commit" ]; then
186 if [ "$2" != "--forced" -a -z "$forced" ]; then
187 echo -e "Nothing to cook...\n"
188 packages_summary
189 rm -f $LOCK_FILE && exit 0
190 fi
191 fi
192 fi
193 }
195 # Running 'tazbb report' should not pack anything and --verbose option
196 # can be used to display more messages.
197 check_flavors()
198 {
199 # Clean up last results.
200 rm -f $DB_DIR/packlist && touch $DB_DIR/packlist
201 echo ""
202 echo "Checking all files in: $HG_FLAVORS"
203 echo "================================================================================"
204 echo "(checking flavors)" > $DB_DIR/running
205 for flavor in $(cd $HG_FLAVORS ; ls)
206 do
207 [ "$2" = "--verbose" ] && echo "Flavor : $flavor"
208 if [ ! -s $PACKAGES_REPOSITORY/$flavor.flavor ]; then
209 echo $flavor >> $DB_DIR/packlist
210 [ "$1" = "report" ] && echo "Missing : $flavor"
211 echo "Missing flavor : $flavor" >> $DB_DIR/report
212 continue
213 fi
214 for i in $(find $HG_FLAVORS/$flavor -type f); do
215 [ $PACKAGES_REPOSITORY/$flavor.flavor -nt \
216 $i ] && continue
217 echo $flavor >> $DB_DIR/packlist
218 [ "$1" = "report" ] && echo "Refresh : $flavor for $i"
219 echo "Refresh flavor : $flavor" >> $DB_DIR/report
220 continue 2
221 done
222 [ -s $HG_FLAVORS/$flavor/packages.list ] &&
223 for i in $(cat $HG_FLAVORS/$flavor/packages.list); do
224 if [ ! -d $BUILD_WOK/$i ]; then
225 [ "$1" = "report" ] &&
226 echo "Fix flavor for $i: $flavor"
227 echo "Fix flavor for $i: $flavor" >> $DB_DIR/report
228 continue
229 fi
230 [ $PACKAGES_REPOSITORY/$flavor.flavor -nt \
231 $BUILD_WOK/$i/taz ] && continue
232 echo $flavor >> $DB_DIR/packlist
233 [ "$1" = "report" ] && echo "Repack : $flavor for $i"
234 echo "Repack flavor : $flavor" >> $DB_DIR/report
235 continue 2
236 done
237 done
239 # Check for meta flavors
240 for flavor in $(cd $HG_FLAVORS ; ls)
241 do
242 grep -q ^ROOTFS_SELECTION $HG_FLAVORS/$flavor/receipt || continue
243 . $HG_FLAVORS/$flavor/receipt
244 set -- $ROOTFS_SELECTION
245 if [ $PACKAGES_REPOSITORY/$2.flavor -nt \
246 $PACKAGES_REPOSITORY/$flavor.flavor ]; then
247 echo $flavor >> $DB_DIR/packlist
248 [ "$1" = "report" ] && echo "Refresh : $flavor for $2"
249 echo "Refresh meta flavor : $flavor" >> $DB_DIR/report
250 continue
251 fi
252 if grep -q ^$2$ $DB_DIR/packlist ; then
253 echo $flavor >> $DB_DIR/packlist
254 [ "$1" = "report" ] && echo "Repack : $flavor for $2"
255 echo "Repack meta flavor : $flavor" >> $DB_DIR/report
256 continue
257 fi
258 done
259 }
261 # Here we pack all flavors found in the packlist.
262 pack_flavors()
263 {
264 [ -s $DB_DIR/packlist ] || return
265 [ $PACKAGES_REPOSITORY/packages.list -nt /var/lib/tazpkg/packages.list ] &&
266 cp -a $PACKAGES_REPOSITORY/packages.list /var/lib/tazpkg/packages.list
267 cd $PACKAGES_REPOSITORY
268 for flavor in $(cat $DB_DIR/packlist)
269 do
270 tazlito pack-flavor $flavor
271 # Remove flavor from the packlist and empty lines for HTML <pre>.
272 sed -i /"^$flavor$"/d $DB_DIR/packlist
273 sed -i '/^$/d' $DB_DIR/packlist
274 done
275 cd - > /dev/null
276 }
278 # Running 'tazbb report' should not cook anything and --verbose option
279 # can be used to display more messages.
280 check_wok()
281 {
282 # Clean up last results.
283 rm -f $DB_DIR/cooklist && touch $DB_DIR/cooklist
284 rm -f $DB_DIR/report && touch $DB_DIR/report
285 rm -f $DB_DIR/unbuilt && touch $DB_DIR/unbuilt
286 echo "Checking all files in: $HG_WOK"
287 echo "================================================================================"
288 echo "(checking wok)" > $DB_DIR/running
289 TOOLCHAIN="$(. $HG_WOK/slitaz-toolchain/receipt ; echo $DEPENDS)"
290 TOOLCHAIN="$TOOLCHAIN glibc linux" # break cook loop
291 for pkg in $HG_WOK/*
292 do
293 EXTRAVERSION=""
294 WANTED=""
295 BUILD_DEPENDS=""
296 [ -s $pkg/receipt ] || continue
297 . $pkg/receipt
298 [ "$2" = "--verbose" ] && echo "Package : $PACKAGE"
299 # Skip blocked packages.
300 if grep -qs "^$PACKAGE$" $DB_DIR/blocked; then
301 echo "Blocked : $PACKAGE ($VERSION)" && continue
302 fi
304 # Some packages may compute VERSION at cook time (bristuff)
305 if grep -q ^get_version $pkg/receipt; then
306 . $BUILD_WOK/$PACKAGE/taz/*/receipt
307 fi
309 # First check if package exit. Package naming _must_ be in the form of:
310 # $PACKAGE-$VERSION or $PACKAGE-${VERSION}$EXTRAVERSION (Kernel string).
311 if [ ! -f $PACKAGES_REPOSITORY/$PACKAGE-$VERSION.tazpkg ]; then
312 [ -z "$EXTRAVERSION" ] && EXTRAVERSION="_$KERNEL"
313 if [ ! -f $PACKAGES_REPOSITORY/$PACKAGE-${VERSION}$EXTRAVERSION.tazpkg ]; then
314 [ "$1" = "report" ] && echo "Missing : $PACKAGE ($VERSION)"
315 echo "Missing : $PACKAGE ($VERSION)" >> $DB_DIR/report
316 echo "$PACKAGE" >> $DB_DIR/cooklist
317 fi
318 else
319 # Check if package is up-to-date.
320 PKG_YEAR=`date -u -r $PACKAGES_REPOSITORY/$PACKAGE-${VERSION}${EXTRAVERSION}.tazpkg '+%Y'`
321 PKG_DATE=`date -u -r $PACKAGES_REPOSITORY/$PACKAGE-${VERSION}${EXTRAVERSION}.tazpkg '+%m%d%H%M'`
322 for file in `find $pkg -type f`
323 do
324 FILE_YEAR=`date -u -r $file '+%Y'`
325 FILE_DATE=`date -u -r $file '+%m%d%H%M'`
326 [ "$2" = "--verbose" ] && echo " -> Checking: $file"
327 if [ "$FILE_YEAR" -ge "$PKG_YEAR" -a "$FILE_DATE" -gt "$PKG_DATE" ] && ! grep -q $PACKAGE $DB_DIR/cooklist; then
328 [ "$1" = "report" ] && echo "Refresh : $PACKAGE ($VERSION)"
329 echo "Refresh : $PACKAGE ($VERSION)" >> $DB_DIR/report
330 echo "$PACKAGE" >> $DB_DIR/cooklist
331 fi
332 done
333 fi
334 # Now check if package is built and not already in the list.
335 if [ ! -d $BUILD_WOK/$PACKAGE/taz ] && ! grep -q $PACKAGE $DB_DIR/cooklist; then
336 [ "$1" = "report" ] && echo "Unbuilt : $PACKAGE ($VERSION)"
337 echo "Unbuilt : $PACKAGE ($VERSION)" >> $DB_DIR/report
338 echo "$PACKAGE" >> $DB_DIR/cooklist
339 fi
340 if ! grep -q $PACKAGE $DB_DIR/cooklist; then
341 case " $TOOLCHAIN " in
342 *\ $PACKAGE\ *) continue;;
343 esac
344 case "$PACKAGE" in
345 tazbb|tazwok|tazpkg) continue;;
346 esac
347 for dep in $BUILD_DEPENDS $TOOLCHAIN ; do
348 [ $BUILD_WOK/$PACKAGE/taz -nt $BUILD_WOK/$dep/taz ] && continue
349 [ "$1" = "report" ] && echo "Refresh : $PACKAGE (older than $dep)"
350 echo "Refresh : $PACKAGE (older than $dep)" >> $DB_DIR/report
351 echo "$PACKAGE" >> $DB_DIR/cooklist
352 break
353 done
354 fi
355 # Rebuild unbuilt packages list with link to log file. This list
356 # is also generated by cook_inslall to have real time stats.
357 if [ ! -d $BUILD_WOK/$PACKAGE/taz ]; then
358 echo "<a href=\"log.php?package=$(escape $PACKAGE)$LOG_SUFFIX\">$PACKAGE</a>" \
359 >> $DB_DIR/unbuilt
360 fi
361 done
362 packages_summary
363 }
365 # Create a new cooklist and summary (dont modify report) so 'tazbb cook-commit'
366 # can cook last changes.
367 check_commit()
368 {
369 echo "(checking commit)" > $DB_DIR/running
370 cd $HG_WOK
371 # Clean up last results.
372 rm -f $DB_DIR/cooklist && touch $DB_DIR/cooklist
373 # Get the name of modified packages by the revision range. +1 last
374 # commit was build by the previous build.
375 LAST_REV=$(($LAST_REV+1))
376 echo -e "Will cook from revision $LAST_REV to $NEW_REV\n"
377 for file in `hg log --rev=$LAST_REV:$NEW_REV --template '{files}\n'`
378 do
379 pkg=`echo $file | cut -d "/" -f 1`
380 if ! grep -q ^$pkg$ $DB_DIR/cooklist; then
381 if [ -f $pkg/receipt ]; then
382 . $pkg/receipt
383 echo "Commit : $PACKAGE ($VERSION)" >> $DB_DIR/report
384 echo "$PACKAGE" >> $DB_DIR/cooklist
385 fi
386 fi
387 done
388 packages_summary
389 }
391 # Cook one package
392 cook_package()
393 {
394 EXTRAVERSION=""
395 DEPENDS=""
396 BUILD_DEPENDS=""
397 SOURCE=""
398 WANTED=""
399 echo "(cooking <a href=\"log.php?package=$(escape $pkg)$LOG_SUFFIX\">$pkg</a>)" > $DB_DIR/running
400 tazwok clean $pkg
401 script -c "tazbb check-receipt $pkg && echo 'install' | tazwok cook $pkg" $LOG_DIR/$pkg.log
402 # Install new package (important for new shared libs). Note
403 # that tests are done separatly with 'test_packages' and should
404 # be done by tazwok.
405 if [ -f $BUILD_WOK/$pkg/taz/*/receipt ]; then
406 TAZBB_NO_INSTALL=""
407 . $BUILD_WOK/$pkg/taz/*/receipt
408 [ -n "$TAZBB_NO_INSTALL" ] && return 0
409 echo "(installing $PACKAGE-${VERSION}$EXTRAVERSION.tazpkg)" \
410 > $DB_DIR/running
411 script -ac "yes | tazpkg install \
412 $PACKAGES_REPOSITORY/$PACKAGE-${VERSION}$EXTRAVERSION.tazpkg --forced" \
413 $LOG_DIR/$pkg.log
414 return 0
415 fi
416 return 1
417 }
419 # Sort list according WANTED and BUILD_DEPENDS
420 sort_cook_list()
421 {
422 sort | while read pkg; do
423 echo -n "$pkg"
424 WANTED=""
425 BUILD_DEPENDS=""
426 . $BUILD_WOK/$pkg/receipt
427 MISSING=""
428 for i in $WANTED $BUILD_DEPENDS ; do
429 # Verify that the dependancy exists and is older
430 [ -f $BUILD_WOK/$i/taz/*/receipt ] &&
431 [ $BUILD_WOK/$pkg/taz/*/receipt \
432 -nt $BUILD_WOK/$i/taz/*/receipt ] && continue
433 WANTED=""
434 [ -f $BUILD_WOK/$i/receipt ] &&
435 . $BUILD_WOK/$i/receipt
436 # This dependancy may be cooked
437 # by another package
438 [ -n "$WANTED" ] && i=$WANTED
439 case " $MISSING " in
440 *\ $i\ *);;
441 *) echo -n " $i";;
442 esac
443 MISSING="$MISSING $i"
444 done
445 echo ""
446 done | awk '{ deps[$1] = $0; }
447 END {
448 k=0;
449 while (1) {
450 skipped = 0;
451 done = 0;
452 for (entry in deps) {
453 for (i = split(deps[entry], pkg, " "); i > 1; i--)
454 if (deps[pkg[i]] != "") break;
455 if (i == 1) {
456 cook[k++] = pkg[1];
457 deps[pkg[1]] = "";
458 done++;
459 }
460 else if (i > 1) skipped++;
461 }
462 if (skipped == 0) break;
463 if (done == 0) { # cross deps !!
464 for (entry in deps) {
465 if (split(deps[entry], pkg, " ") > 1)
466 print pkg[1];
467 }
468 break;
469 }
470 }
471 while (k > 0) print cook[--k];
472 }
473 '
474 }
476 # Here we cook all packages found in the cooklist.
477 cook_install()
478 {
479 echo "" > $DB_DIR/unbuilt
480 for pkg in `cat $DB_DIR/cooklist | sort_cook_list`
481 do
482 if ! cook_package $pkg; then
483 # Link to build log.
484 echo "<a href=\"log.php?package=$(escape $pkg)$LOG_SUFFIX\">$pkg</a>" >> \
485 $DB_DIR/unbuilt
486 fi
487 missing_depends="$(check_depends_pkg $pkg)"
488 if [ -n "$missing_depends" ]; then
489 cat >> $LOG_DIR/$pkg.log <<EOT
491 Update $pkg receipt for DEPENDS :
492 The package $pkg depends on packages $missing_depends
494 EOT
495 # Unbuild package
496 rm -rf $BUILD_WOK/$pkg/taz
497 # Link to build log.
498 echo "<a href=\"log.php?package=$(escape $pkg)$LOG_SUFFIX\">$pkg</a>" >> \
499 $DB_DIR/unbuilt
500 fi
501 # Remove package from the cooklist and empty lines for HTML <pre>.
502 sed -i /"^$pkg$"/d $DB_DIR/cooklist
503 sed -i '/^$/d' $DB_DIR/cooklist
504 packages_summary_update
505 done
506 }
508 # Check for misc variables
509 check_variables()
510 {
511 PACKAGE=""
512 VERSION=""
513 EXTRAVERSION=""
514 CATEGORY=""
515 SHORT_DESC=""
516 MAINTAINER=""
517 WEB_SITE=""
518 PACKED_SIZE=""
519 UNPACKED_SIZE=""
520 . $BUILD_WOK/$1/receipt
521 if [ "$PACKAGE" != "$1" ]; then
522 echo "The PACKAGE variable should be $1"
523 return 1
524 fi
525 if [ -z "$VERSION" ]; then
526 echo "No VERSION in $1"
527 return 1
528 fi
529 if [ -z "$SHORT_DESC" ]; then
530 echo "No SHORT_DESC in $1"
531 return 1
532 fi
533 case "$MAINTAINER" in
534 '') echo "No MAINTAINER in $1"
535 return 1 ;;
536 *\<*|*\>*)
537 echo "Invalid MAINTAINER in $1"
538 return 1 ;;
539 *@*) ;;
540 *) echo "No email address for MAINTAINER in $1"
541 return 1 ;;
542 esac
543 if [ -z "$WEB_SITE" ]; then
544 echo "No WEB_SITE in $1"
545 return 1
546 fi
547 if [ -n "$EXTRAVERSION" ]; then
548 echo "Hardcoded EXTRAVERSION in $1"
549 return 1
550 fi
551 if [ -n "$PACKED_SIZE" ]; then
552 echo "Hardcoded PACKED_SIZE in $1"
553 return 1
554 fi
555 if [ -n "$UNPACKED_SIZE" ]; then
556 echo "Hardcoded UNPACKED_SIZE in $1"
557 return 1
558 fi
559 case " base-system x-window utilities network graphics multimedia \
560 office development system-tools security games misc meta \
561 non-free " in
562 *\ $CATEGORY\ *);;
563 *) echo "Invalid CATEGORY in $1 : $CATEGORY"
564 return 1;
565 esac
566 return 0
567 }
569 # Check for WANTED version
570 check_wanted_version()
571 {
572 WANTED=""
573 . $BUILD_WOK/$1/receipt
574 if [ -n "$WANTED" ]; then
575 expected=$VERSION
576 VERSION=
577 . $BUILD_WOK/$WANTED/receipt
578 if [ "$VERSION" != "$expected" ]; then
579 echo "$1: expected wanted version $expected, found $VERSION"
580 return 1
581 fi
582 fi
583 return 0
584 }
586 # Check for loop in BUILD_DEPENDS/WANTED
587 check_build_depends()
588 {
589 local i
590 BUILD_DEPENDS=""
591 WANTED=""
592 . $BUILD_WOK/$1/receipt
593 for i in $BUILD_DEPENDS $WANTED ; do
594 case " $2 " in
595 *\ $i\ *) echo "Loop in BUILD_DEPENDS/WANTED chain $2 $i"
596 return 1 ;;
597 *) check_build_depends $i "$2 $1" || return 1 ;;
598 esac
599 done
600 return 0
601 }
603 # Build depends_to_skip list with packages to remove from depends_to_add list
604 # These packages are already present in depends_to_add trees
605 scan_depends_to_skip()
606 {
607 local i
608 case " $depends_to_skip " in
609 *\ $1\ *) return;;
610 esac
611 [ -d $BUILD_WOK/$1 ] || return
612 DEPENDS=""
613 . $BUILD_WOK/$1/receipt
614 for i in $DEPENDS ; do
615 case " $depends_to_add " in
616 *\ $i\ *) depends_to_skip="$depends_to_skip $i";;
617 esac
618 done
619 for i in $DEPENDS ; do
620 scan_depends_to_skip $i
621 done
622 }
624 # Reduce depends list by scanning nested depends
625 show_missing_depends()
626 {
627 local i
628 depends_to_add=""
629 depends_to_skip="$2"
630 for i in $1 ; do
631 case " $depends_to_add " in
632 *\ $i\ *) continue;;
633 esac
634 depends_to_add="$depends_to_add$i "
635 done
636 for i in $depends_to_add ; do
637 scan_depends_to_skip $i
638 done
639 for i in $depends_to_add ; do
640 case " $depends_to_skip " in
641 *\ $i\ *) continue;;
642 esac
643 echo -n "$i "
644 done
645 }
647 # Build all_depends variable
648 scan_dep()
649 {
650 local i
651 all_depends="$all_depends$PACKAGE "
652 for i in $DEPENDS $SUGGESTED ; do
653 case " $all_depends " in
654 *\ $i\ *) continue;;
655 esac
656 [ -d $BUILD_WOK/$i ] || {
657 all_depends="$all_depends$i "
658 continue
659 }
660 DEPENDS=""
661 SUGGESTED=""
662 . $BUILD_WOK/$i/receipt
663 scan_dep
664 done
665 }
667 # Check for ELF file
668 is_elf()
669 {
670 [ "$(dd if=$1 bs=1 skip=1 count=3 2> /dev/null)" = "ELF" ]
671 }
673 # Print shared library dependencies
674 ldd()
675 {
676 LD_PRELOAD="" LD_TRACE_LOADED_OBJECTS=1 /lib/ld*.so $1 2> /dev/null
677 }
679 # scan a file for shared libraries and display according package names
680 check_depends_file()
681 {
682 file=$1
683 is_elf $file || continue
684 case "$file" in
685 *.o|*.ko|*.ko.gz) continue;;
686 esac
687 [ -s /tmp/files.list.tazbb$$ ] ||
688 unlzma -c $PACKAGES_REPOSITORY/files.list.lzma >/tmp/files.list.tazbb$$
689 ldd $file | while read lib rem; do
690 case "$lib" in
691 statically|linux-gate.so*|ld-*.so|*/ld-*.so)
692 continue;;
693 esac
694 for dep in $(grep $lib /tmp/files.list.tazbb$$ | cut -d: -f1); do
695 case " $all_depends " in
696 *\ $dep\ *) continue 2;;
697 esac
698 for vdep in $(grep $dep $PACKAGES_REPOSITORY/packages.equiv | cut -d= -f1); do
699 case " $all_depends " in
700 *\ $vdep\ *) continue 3;;
701 esac
702 done
703 done
704 [ -n "$dep" ] || dep="UNKNOWN"
705 all_depends="$all_depends $dep"
706 if [ -n "$VERBOSE" ]; then
707 echo "${file#*fs} depends on package $dep for the shared library $lib" 1>&2
708 fi
709 echo -n "$dep "
710 done
711 }
713 DEFAULT_DEPENDS="glibc-base"
715 # scan a package for shared libraries and display missing package in DEPENDS
716 check_depends_pkg()
717 {
718 pkg=$1
719 echo "(checking depends for $pkg)" > $DB_DIR/running
720 tmp=/tmp/tazbb$$
721 mkdir $tmp
722 package=$(basename $pkg)
723 if ! cd ${package%%-*}*/taz/${package%.tazpkg}/.. 2> /dev/null; then
724 cd $tmp
725 tazpkg extract $pkg > /dev/null 2>&1
726 fi
727 . */receipt
728 all_depends="$DEFAULT_DEPENDS "
729 scan_dep
730 toadd=$(find */fs -type f | while read file ; do
731 check_depends_file $file
732 done)
733 . */receipt
734 rm -rf */
735 cd - > /dev/null
736 rm -rf $tmp
737 show_missing_depends "$toadd" "$DEPENDS $SUGGESTED"
738 }
740 check_depends_this_file()
741 {
742 file=$1
743 all_depends="$DEFAULT_DEPENDS "
744 scan_dep
745 check_depends_file $file
746 }
748 # Remove old packages in the build wok and clean pkgs repository. The
749 # Hg wok is copied into the build wok so packages removed by hg must be
750 # removed. To remove old packages in the repository we look into the
751 # build wok and dont remove unbuilt packages. Clean-up will also remove
752 # all corrupted packages.
753 clean_up()
754 {
755 touch $DB_DIR/removed
756 echo -e "\nCleaning the build wok, old and corrupted packages...\n"
757 echo "(cleaning)" > $DB_DIR/running
758 for pkg in `ls $BUILD_WOK`
759 do
760 if [ ! -d $HG_WOK/$pkg ]; then
761 case $2 in
762 --dry-run)
763 echo "Removing directory : $pkg" ;;
764 --verbose)
765 echo "Removing directory : $pkg"
766 rm -rf $BUILD_WOK/$pkg ;;
767 *)
768 rm -rf $BUILD_WOK/$pkg ;;
769 esac
770 fi
771 done
772 # Build a packages list with EXTRAVERSION so we can grep into it.
773 rm -f $DB_DIR/packaged && touch $DB_DIR/packaged
774 for receipt in $BUILD_WOK/*/taz/*/receipt
775 do
776 EXTRAVERSION=""
777 . $receipt
778 echo "$PACKAGE-${VERSION}$EXTRAVERSION.tazpkg" >> $DB_DIR/packaged
779 done
780 for pkg in `cd $PACKAGES_REPOSITORY && ls *.tazpkg`
781 do
782 if ! grep -q "^$pkg$" $DB_DIR/packaged; then
783 case $2 in
784 --dry-run)
785 echo "Removing package : $pkg" ;;
786 --verbose)
787 echo "Removing package : $pkg"
788 echo "$pkg" >> $DB_DIR/removed
789 rm -f $PACKAGES_REPOSITORY/$pkg ;;
790 *)
791 echo "$pkg" >> $DB_DIR/removed
792 rm -f $PACKAGES_REPOSITORY/$pkg ;;
793 esac
794 fi
795 done
796 # Remove all corrupted packages
797 for pkg in `cat $DB_DIR/corrupted | awk '{ print $3 }'`
798 do
799 case $2 in
800 --dry-run)
801 echo "Removing corrupted: $pkg" ;;
802 --verbose)
803 echo "Removing corrupted: $pkg"
804 echo "$pkg" >> $DB_DIR/removed
805 rm -rf $PACKAGES_REPOSITORY/$pkg ;;
806 *)
807 echo "$pkg" >> $DB_DIR/removed
808 rm -rf $PACKAGES_REPOSITORY/$pkg ;;
809 esac
810 done
811 echo ""
812 # Keep the 20 last removed packages list.
813 cat $DB_DIR/removed | tail -n 20 > /tmp/removed.tail
814 mv -f /tmp/removed.tail $DB_DIR/removed
815 # Clean packages stuff/ directory
816 echo -e "\nCleaning the build wok stuff/ directories...\n"
817 for pkg in `ls $BUILD_WOK`
818 do
819 if [ -d "$BUILD_WOK/$pkg/stuff" ]; then
820 cd $BUILD_WOK/$pkg
821 for file in `find stuff -type f`
822 do
823 if [ ! -f "$HG_WOK/$pkg/$file" ]; then
824 echo "Removing: $pkg/$file"
825 rm $file
826 fi
827 done
828 fi
829 done
830 }
832 blocked_urls()
833 {
834 rm -f $DB_DIR/blocked.urls
835 for pkg in `cat $DB_DIR/blocked`
836 do
837 if [ -f $LOG_DIR/$pkg.log ]; then
838 echo "<a href=\"log.php?package=$(escape $pkg)$LOG_SUFFIX\">$pkg</a>" >> \
839 $DB_DIR/blocked.urls
840 else
841 echo "$pkg" >> $DB_DIR/blocked.urls
842 fi
843 done
844 }
846 # 4k, not a meta or a get-* package and no files = buggy package
847 test_packages()
848 {
849 echo -e "\nTesting all packages in: $PACKAGES_REPOSITORY"
850 echo "================================================================================"
851 echo "(testing packages)" > $DB_DIR/running
852 rm -f $DB_DIR/corrupted && touch $DB_DIR/corrupted
853 for pkg in $PACKAGES_REPOSITORY/*.tazpkg
854 do
855 tmp=/tmp/bb-test.$$
856 CATEGORY=""
857 if du $pkg | grep -qw '^4' && ! echo `basename $pkg` | grep -q '^get-'; then
858 mkdir -p $tmp && cd $tmp
859 cpio -i receipt >/dev/null 2>&1 < $pkg
860 . ./receipt
861 if [ "$CATEGORY" != "meta" ]; then
862 [ "$2" = "--verbose" ] && echo "Testing: $PACKAGE"
863 cpio -i fs.cpio.gz >/dev/null 2>&1 < $pkg
864 cpio -i fs.cpio.lzma >/dev/null 2>&1 < $pkg
865 if [ ! -f fs.cpio.gz -a ! -f fs.cpio.lzma ]; then
866 echo "Missing filesystem `basename $pkg`"
867 if [ -f $LOG_DIR/$PACKAGE.log ];then
868 echo "Missing filesystem `basename $pkg` <a href=\"log.php?package=$(escape $PACKAGE)$LOG_SUFFIX\">Log</a>" \
869 >> $DB_DIR/corrupted
870 else
871 echo "Missing filesystem `basename $pkg`" \
872 >> $DB_DIR/corrupted
873 fi
874 else
875 ( zcat fs.cpio.gz 2> /dev/null || \
876 unlzma -c fs.cpio.lzma ) | \
877 cpio -id >/dev/null 2>&1
878 files=`find fs -type f -o -type l`
879 if [ -z "$files" ]; then
880 echo "Empty filesystem `basename $pkg`"
881 if [ -f $LOG_DIR/$PACKAGE.log ]; then
882 echo "Empty filesystem `basename $pkg` <a href=\"log.php?package=$(escape $PACKAGE)$LOG_SUFFIX\">Log</a>" \
883 >> $DB_DIR/corrupted
884 else
885 echo "Empty filesystem `basename $pkg`" \
886 >> $DB_DIR/corrupted
887 fi
888 fi
889 fi
890 fi
891 cd .. && rm -rf $tmp
892 fi
893 done
894 packages_summary_update
895 echo ""
896 }
898 # Generate flavor list
899 gen_flavor_list()
900 {
901 cd $PACKAGES_REPOSITORY
902 noheader=""
903 for i in *.flavor; do
904 tazlito show-flavor $i --brief $noheader
905 noheader="--noheader"
906 done > flavors.list
907 cd - > /dev/null
908 }
910 case "$1" in
911 list-pkgs)
912 # List last cooked packages.
913 list_packages ;;
914 report)
915 # Run in report mode. If an update is done we must cook-all to
916 # rebuild all updated packages.
917 [ "$2" == "--update" ] && update_wok $@ || echo ""
918 check_wok $@
919 check_flavors $@
920 test_packages $@
921 show_report ;;
922 cook)
923 # Cook, install and log a single package build.
924 if [ -z $2 ]; then
925 echo "Please specify a package on the command line."
926 rm -f $LOCK_FILE && exit 0
927 fi
928 pkg=$2
929 echo "Starting to cook and install: $pkg"
930 if ! cook_package $pkg; then
931 echo "Unable to install: $pkg"
932 fi ;;
933 cook-all)
934 # Update wok, gen report (with cooklist), cook all packages, test,
935 # clean, gen new report and lists.
936 update_wok $@
937 check_wok $@
938 cook_install
939 test_packages $@
940 check_flavors $@
941 pack_flavors
942 clean_up $@
943 check_wok $@
944 echo "(generating lists)" > $DB_DIR/running
945 tazwok gen-list --text
946 check_flavors $@
947 gen_flavor_list
948 echo "" ;;
949 cook-commit)
950 # Cook all packages affected by the last commits in the wok.
951 # Clean up is done only by cook-all to avoid rebuild of corrupted
952 # packages on each commit.
953 update_wok $@
954 check_commit
955 cook_install
956 test_packages $@
957 check_flavors $@
958 pack_flavors
959 check_wok $@
960 check_flavors $@
961 echo "(generating lists)" > $DB_DIR/running
962 tazwok gen-list --text
963 gen_flavor_list
964 echo "" ;;
965 block)
966 # Add a pkg name to the list of blocked packages.
967 echo ""
968 if grep -qs "^$2$" $DB_DIR/blocked; then
969 echo -e "$2 is already in the blocked packages list."
970 else
971 echo -n "Adding $2 to : $DB_DIR/blocked... "
972 echo "$2" >> $DB_DIR/blocked && echo "Done"
973 if grep -q "^$2$" $DB_DIR/cooklist; then
974 echo -n "Removing $2 from : $DB_DIR/cooklist... "
975 sed -i /"^$2$"/d $DB_DIR/cooklist && echo "Done"
976 packages_summary_update
977 fi
978 fi
979 blocked_urls
980 echo "" ;;
981 unblock)
982 # Remove a pkg name from the list of blocked packages.
983 echo ""
984 if grep -qs "^$2$" $DB_DIR/blocked; then
985 echo -n "Removing $2 from : $DB_DIR/blocked... "
986 sed -i /"^$2$"/d $DB_DIR/blocked
987 sed -i '/^$/d' $DB_DIR/blocked && echo "Done"
988 echo -n "Adding $2 to : $DB_DIR/cooklist... "
989 echo "$2" >> $DB_DIR/cooklist && echo "Done"
990 packages_summary_update
991 else
992 echo -e "$2 is not in the blocked packages list."
993 fi
994 blocked_urls
995 echo "" ;;
996 test-pkgs)
997 # Start a test suite on all builded packages.
998 test_packages $@ ;;
999 test-suite)
1000 # Start a test suite on all builded package and the wok using
1001 # the great 'tazwok check'.
1003 # test_packages > $LOG_DIR/test-suite.log
1004 # tazwok check >> $LOG_DIR/test-suite.log
1006 test_packages $@
1007 script -c "tazwok check" $LOG_DIR/test-suite.log ;;
1008 mail)
1009 # Tazbbmail Pythom script wrapper.
1010 PACKAGE=$2
1011 tazbbmail $PACKAGE ;;
1012 clean-up)
1013 # Remove old packages and generate new packages lists.
1014 update_wok $@
1015 clean_up $@
1016 packages_summary_update
1017 [ "$2" != "--dry-run" ] && tazwok gen-list --text ;;
1018 clean-log)
1019 logs=`ls $LOG_DIR | wc -l`
1020 echo -n "Cleaning: $LOG_DIR... "
1021 rm -rf $LOG_DIR/*
1022 echo "$logs log removed" ;;
1023 check-receipt)
1024 check_variables $2 &&
1025 check_wanted_version $2 &&
1026 check_build_depends $2 ""
1027 exit $? ;;
1028 check-depends)
1029 case "$2" in
1030 wok)
1031 for pkg in $PACKAGES_REPOSITORY/*.tazpkg ; do
1032 missing_depends="$(check_depends_pkg $pkg)"
1033 [ -n "$missing_depends" ] &&
1034 echo "The package $pkg depends on $missing_depends."
1035 done ;;
1036 package)
1037 pkg=$3
1038 VERBOSE=$4
1039 missing_depends="$(check_depends_pkg $pkg)"
1040 [ -n "$missing_depends" ] &&
1041 echo "The package $pkg depends on $missing_depends."
1042 ;;
1043 file)
1044 file=3
1045 VERBOSE=$4
1046 missing_depends="$(check_depends_this_file $file)"
1047 [ -n "$missing_depends" ] &&
1048 echo "The file $file depends on $missing_depends."
1049 ;;
1050 *) cat <<EOT
1051 check-depends wok check every package in wok.
1052 check-depends package <pkg> check one package.
1053 check-depends file <filename> check one file only.
1054 EOT
1055 ;;
1056 esac ;;
1057 *)
1058 usage ;;
1059 esac
1061 echo "" > $DB_DIR/running
1062 rm -f $LOCK_FILE /tmp/files.list.tazbb$$
1064 exit 0