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