cookutils view cook @ rev 161
Add branch/rev support in svn
| author | Christophe Lincoln <pankso@slitaz.org> | 
|---|---|
| date | Sun May 15 00:14:41 2011 +0200 (2011-05-15) | 
| parents | c98ac2df8dfb | 
| children | f1c83137e788 | 
 line source
     1 #!/bin/sh
     2 #
     3 # Cook - A tool to cook and generate SliTaz packages. Read the README
     4 # before adding or modifing any code in cook!
     5 #
     6 # Copyright (C) SliTaz GNU/Linux - GNU gpl v3
     7 # Author: Christophe Lincoln <pankso@slitaz.org>
     8 #
    10 [ -f "/etc/slitaz/cook.conf" ] && . /etc/slitaz/cook.conf
    11 [ -f "cook.conf" ] && . ./cook.conf
    13 # Share DB and status with the Cooker.
    14 activity="$CACHE/activity"
    15 command="$CACHE/command"
    16 broken="$CACHE/broken"
    17 blocked="$CACHE/blocked"
    19 #
    20 # Functions
    21 #
    23 usage() {
    24 	cat << EOT
    26 $(echo -e "\033[1m$(gettext "Usage:")\033[0m") cook [package|command] [list|--option]
    28 $(echo -e "\033[1m$(gettext "Commands:")\033[0m")
    29   usage|help      $(gettext "Display this short usage.")
    30   setup           $(gettext "Setup your build environment.")
    31   test            $(gettext "Test environment and cook a package.")
    32   list-wok        $(gettext "List packages in the wok.")
    33   search          $(gettext "Simple packages search function.")
    34   new             $(gettext "Create a new package with a receipt".)
    35   list            $(gettext "Cook a list of packages.") 
    36   clean-wok       $(gettext "Clean-up all packages files.")
    37   clean-src       $(gettext "Clean-up all packages sources.")
    38   pkglist         $(gettext "Create all packages.* lists.")
    40 $(echo -e "\033[1m$(gettext "Options:")\033[0m")
    41   --clean|-c      Cook : $(gettext "clean the package in the wok.")
    42   --install|-i    Cook : $(gettext "cook and install the package.")
    43   --getsrc|-gs    Cook : $(gettext "get the package source tarball.")
    44   --block|-b      Cook : $(gettext "Block a package so cook will skip it.")
    45   --unblock|-ub   Cook : $(gettext "Unblock a blocked package.")
    46   --wok|-w        Setup: $(gettext "create also a wok from Hg repo.")
    48 EOT
    49 	exit 0
    50 }
    52 # Be sure we're root.
    53 check_root() {
    54 	[ $(id -u) != 0 ] && gettext -e "\nYou must be root to cook.\n\n" && exit 0
    55 }
    57 separator() {
    58 	echo "================================================================================"
    59 }
    61 status() {
    62 	echo -en "\\033[70G[ "
    63 	if [ $? = 0 ]; then
    64 		echo -en "\\033[1;32mOK"
    65 	else
    66 		echo -en "\\033[1;31mFailed"
    67 	fi
    68 	echo -e "\\033[0;39m ]"
    69 }
    71 # Log activities, we want first letter capitalized.
    72 log() {
    73 	grep ^[A-Z] | \
    74 		sed s"#^[A-Z]\([^']*\)#$(date '+%Y-%m-%d %H:%M') : \0#" >> $activity
    75 }
    77 # We don't want these escapes in web interface.
    78 clean_log() {
    79 	sed -i -e s'|\[70G\[ \[1;32m| |' \
    80 		-e s'|\[0;39m \]||' $LOGS/$pkg.log
    81 }
    83 # Log broken packages.
    84 broken() {
    85 	if ! grep -q "^$pkg$" $broken; then
    86 		echo "$pkg" >> $broken
    87 	fi
    88 }
    90 # Be sure package exists in wok.
    91 check_pkg_in_wok() {
    92 	if [ ! -d "$WOK/$pkg" ]; then
    93 		gettext -e "\nUnable to find package in the wok:"
    94 		echo -e " $pkg\n" && exit 1
    95 	fi
    96 }
    98 if_empty_value() {
    99 	if [ -z "$value" ]; then
   100 		gettext "QA: empty variable:"; echo -e " ${var}=\"\"\n"
   101 		exit 1
   102 	fi
   103 }
   105 # Initialize files used in $CACHE
   106 init_db_files() {
   107 	gettext "Creating directories structure in:"; echo " $SLITAZ"
   108 	mkdir -p $WOK $PKGS $SRC $CACHE $LOGS
   109 	gettext "Creating DB files in:"; echo " $CACHE"
   110 	for f in $activity $command $broken $blocked
   111 	do
   112 		touch $f
   113 	done
   114 }
   116 # QA: check a receipt consistency before building.
   117 receipt_quality() {
   118 	gettext -e "QA: checking package receipt...\n"
   119 	unset online
   120 	if ifconfig | grep -q -A 1 "^[a-z]*[0-9]" | fgrep 'addr:'; then
   121 		online="online"
   122 	fi
   123 	for var in PACKAGE VERSION CATEGORY SHORT_DESC MAINTAINER WEB_SITE
   124 	do
   125 		unset value
   126 		value=$(grep ^$var= $receipt | cut -d \" -f 2)
   127 		case "$var" in
   128 			PACKAGE|VERSION|SHORT_DESC)
   129 				if_empty_value ;;
   130 			CATEGORY)
   131 				[ -z "$value" ] && value="empty"
   132 				valid="base-system x-window utilities network graphics \
   133 					multimedia office development system-tools security games \
   134 					misc meta non-free"
   135 				if ! echo "$valid" | grep -q -w "$value"; then
   136 					gettext "QA: unknown category:"; echo -e " $value\n"
   137 					exit 1
   138 				fi ;;
   139 			WEB_SITE)
   140 				# We don't check WGET_URL since if dl is needed it will fail.
   141 				# Break also if we're not online. Here error is not fatal.
   142 				if_empty_value
   143 				[ -z "$online" ] || break
   144 				if ! busybox wget -s $value 2>/dev/null; then
   145 					gettext "QA: Unable to reach:"; echo -e " $value"
   146 				fi ;;
   147 		esac
   148 	done
   149 }
   151 # Executed before sourcing a receipt.
   152 unset_receipt() {
   153 	unset DEPENDS BUILD_DEPENDS WANTED EXTRAVERSION WGET_URL PROVIDE TARBALL
   154 }
   156 # Paths used in receipt and by cook itself.
   157 set_paths() {
   158 	pkgdir=$WOK/$PACKAGE
   159 	src=$pkgdir/source/$PACKAGE-$VERSION
   160 	taz=$pkgdir/taz
   161 	pack=$taz/$PACKAGE-${VERSION}${EXTRAVERSION}
   162 	fs=$pack/fs
   163 	stuff=$pkgdir/stuff
   164 	install=$pkgdir/install
   165 	if [ "$WANTED" ]; then
   166 		src=$WOK/$WANTED/source/$WANTED-$VERSION
   167 		install=$WOK/$WANTED/install
   168 		wanted_stuff=$WOK/$WANTED/stuff
   169 	fi
   170 	# Old way compatibility.
   171 	_pkg=$install
   172 }
   174 # Create source tarball when URL is a SCM.
   175 create_tarball() {
   176 	gettext "Creating tarball: "; echo "$tarball"
   177 	tar cjf $tarball $pkgsrc || exit 1
   178 	mv $tarball $SRC && rm -rf $pkgsrc
   179 }
   181 # Get package source. For SCM we are in cache so clone here and create a
   182 # tarball here.
   183 get_source() {
   184 	pwd=$(pwd)
   185 	pkgsrc=${SOURCE:-$PACKAGE}-$VERSION
   186 	tarball=$pkgsrc.tar.bz2
   187 	case "$WGET_URL" in
   188 		http://*|ftp://*)
   189 			# Busybox Wget is better!
   190 			busybox wget -c -P $SRC $WGET_URL || \
   191 				(echo -e "ERROR: wget $WGET_URL" && exit 1) ;;
   192 		https://*)
   193 			wget -c --no-check-certificate -P $SRC $WGET_URL || \
   194 				(echo -e "ERROR: wget $WGET_URL" && exit 1) ;;
   195 		hg*|mercurial*)
   196 			if $(echo "$WGET_URL" | fgrep -q "hg|"); then
   197 				url=${WGET_URL#hg|}
   198 			else
   199 				url=${WGET_URL#mercurial|}
   200 			fi
   201 			gettext -e "Getting source from Hg...\n"
   202 			echo "URL: $url"
   203 			gettext "Cloning to: "; echo "$pwd/$pkgsrc"
   204 			hg clone $url $pkgsrc || (echo "ERROR: hg clone $url" && exit 1)
   205 			create_tarball ;;
   206 		git*)
   207 			url=${WGET_URL#git|}
   208 			gettext -e "Getting source from Git...\n"
   209 			echo "URL: $url"
   210 			git clone $url $pkgsrc || (echo "ERROR: git clone $url" && exit 1)
   211 			if [ "$BRANCH" ]; then
   212 				echo "Git branch: $BRANCH"
   213 				cd $pkgsrc && git checkout $BRANCH && cd ..	
   214 			fi
   215 			create_tarball ;;
   216 		cvs*)
   217 			url=${WGET_URL#cvs|}
   218 			mod=$PACKAGE
   219 			[ "$CVS_MODULE" ] && mod=$CVS_MODULE
   220 			gettext -e "Getting source from CVS...\n"
   221 			echo "URL: $url"
   222 			[ "$CVS_MODULE" ] && echo "CVS module: $mod"
   223 			gettext "Cloning to: "; echo "$pwd/$mod"
   224 			cvs -d:$url co $mod && mv $mod $pkgsrc
   225 			create_tarball ;;
   226 		svn*|subversion*)
   227 			if $(echo "$WGET_URL" | fgrep -q "svn|"); then
   228 				url=${WGET_URL#svn|}
   229 			else
   230 				url=${WGET_URL#subversion|}
   231 			fi
   232 			gettext -e "Getting source from SVN...\n"
   233 			echo "URL: $url"
   234 			if [ "$BRANCH" ]; then
   235 				echo t | svn co $url -r $BRANCH $pkgsrc
   236 			else
   237 				echo t | svn co $url $pkgsrc
   238 			fi
   239 			create_tarball ;;
   240 		*)
   241 			gettext -e "\nERROR: Unable to handle:"; echo -e " $WGET_URL \n" | \
   242 				tee -a $LOGS/$PACKAGE.log
   243 			exit 1 ;;
   244 	esac
   245 }
   247 # Extract source package.
   248 extract_source() {
   249 	gettext "Extracting:"; echo " $TARBALL"
   250 	case "$TARBALL" in
   251 		*.tar.gz|*.tgz) tar xzf $SRC/$TARBALL 2>/dev/null ;;
   252 		*.tar.bz2|*.tbz) tar xjf $SRC/$TARBALL 2>/dev/null ;;
   253 		*.tar.lzma) tar xaf $SRC/$TARBALL ;;
   254 		*.tar) tar xf $SRC/$TARBALL ;;
   255 		*.zip|*.xpi) unzip -o $SRC/$TARBALL ;;
   256 		*.xz) unxz -c $SRC/$TARBALL | tar xf - ;;
   257 		*.Z) uncompress -c $SRC/$TARBALL | tar xf - ;;
   258 		*.rpm) rpm2cpio $SRC/$TARBALL | cpio -idm --quiet ;;
   259 	esac
   260 }
   262 # Display cooked package summary.
   263 summary() {
   264 	cd $WOK/$pkg
   265 	[ -d install ] && prod=$(du -sh install | awk '{print $1}' 2>/dev/null)
   266 	fs=$(du -sh taz/* | awk '{print $1}')
   267 	size=$(du -sh $PKGS/$pkg-${VERSION}*.tazpkg | awk '{print $1}')
   268 	files=$(cat taz/$pkg-*/files.list | wc -l)
   269 	cookdate=$(date "+%Y-%m-%d %H:%M")
   270 	sec=$time
   271 	div=$(($time / 60))
   272 	[ "$div" != 0 ] && min="~ ${div}m"
   273 	gettext "Summary for:"; echo " $PACKAGE $VERSION"
   274 	separator
   275 	[ "$prod" ] && echo "Produced   : $prod"
   276 	cat << EOT
   277 Packed     : $fs
   278 Compressed : $size
   279 Files      : $files
   280 Cook time  : ${sec}s $min
   281 Cook date  : $cookdate
   282 $(separator)
   283 EOT
   284 }
   286 # Display debugging error info.
   287 debug_info() {
   288 	echo -e "\nDebug information"
   289 	separator
   290 	echo "Cook date: $(date '+%Y-%m-%d %H:%M')"
   291 	for error in \
   292 		ERROR "No package" "cp: can't" "can't open" "can't cd" \
   293 		"error:" "fatal error:"
   294 	do
   295 		fgrep "$error" $LOGS/$pkg.log
   296 	done
   297 	separator && echo ""
   298 }
   300 # Copy all generic files (locale, pixmaps, .desktop). We use standard paths,
   301 # so some packages need to copy these files with the receipt and genpkg_rules.
   302 copy_generic_files()
   303 {
   304 	# $LOCALE is set in cook.conf
   305 	if [ "$LOCALE"  ]; then
   306 		if [ -d "$_pkg/usr/share/locale" ]; then
   307 			mkdir -p $fs/usr/share/locale
   308 			for i in $LOCALE
   309 			do
   310 				if [ -d "$_pkg/usr/share/locale/$i" ]; then
   311 					cp -a $_pkg/usr/share/locale/$i $fs/usr/share/locale
   312 				fi
   313 			done
   314 		fi
   315 	fi
   317 	# Generic pixmaps copy can be disabled with GENERIC_PIXMAPS="no"
   318 	if [ "$GENERIC_PIXMAPS" != "no" ]; then
   319 		if [ -d "$_pkg/usr/share/pixmaps" ]; then
   320 			mkdir -p $fs/usr/share/pixmaps
   321 			cp -a $_pkg/usr/share/pixmaps/$PACKAGE.png \
   322 				$fs/usr/share/pixmaps 2>/dev/null
   323 			cp -a $_pkg/usr/share/pixmaps/$PACKAGE.xpm \
   324 				$fs/usr/share/pixmaps 2>/dev/null
   325 		fi
   327 		# Custom or homemade PNG pixmap can be in stuff.
   328 		if [ -f "$stuff/$PACKAGE.png" ]; then
   329 			mkdir -p $fs/usr/share/pixmaps
   330 			cp -a $stuff/$PACKAGE.png $fs/usr/share/pixmaps
   331 		fi
   332 	fi
   334 	# Desktop entry (.desktop).
   335 	if [ -d "$_pkg/usr/share/applications" ]; then
   336 		cp -a $_pkg/usr/share/applications $fs/usr/share
   337 	fi
   339 	# Homemade desktop file(s) can be in stuff.
   340 	if [ -d "$stuff/applications" ]; then
   341 		mkdir -p $fs/usr/share
   342 		cp -a $stuff/applications $fs/usr/share
   343 	fi
   344 	if [ -f "$stuff/$PACKAGE.desktop" ]; then
   345 		mkdir -p $fs/usr/share/applications
   346 		cp -a $stuff/$PACKAGE.desktop $fs/usr/share/applications
   347 	fi
   348 }
   350 # Find and strip : --strip-all (-s) or --strip-debug on static libs as well
   351 # as removing uneeded files like in Python packages.
   352 strip_package()
   353 {
   354 	gettext "Executing strip on all files..."
   355 	for dir in $fs/bin $fs/sbin $fs/usr/bin $fs/usr/sbin $fs/usr/games
   356 	do
   357 		if [ -d "$dir" ]; then
   358 			find $dir -type f -exec strip -s '{}' 2>/dev/null \;
   359 		fi
   360 	done
   361 	find $fs -name "*.so*" -exec strip -s '{}' 2>/dev/null \;
   362 	find $fs -name "*.a" -exec strip --strip-debug '{}' 2>/dev/null \;
   363 	status
   365 	# Remove Python .pyc and .pyo from packages.
   366 	if echo "$PACKAGE $DEPENDS" | fgrep -q "python"; then
   367 		gettext "Removing Python compiled files..."
   368 		find $fs -type f -name "*.pyc" -delete 2>/dev/null
   369 		find $fs -type f -name "*.pyo" -delete 2>/dev/null
   370 		status
   371 	fi
   373 	# Remove Perl perllocal.pod and .packlist from packages.
   374 	if echo "$DEPENDS" | fgrep -q "perl"; then
   375 		gettext "Removing Perl compiled files..."
   376 		find $fs -type f -name "perllocal.pod" -delete 2>/dev/null
   377 		find $fs -type f -name ".packlist" -delete 2>/dev/null
   378 		status
   379 	fi
   380 }
   382 # Remove installed deps.
   383 remove_deps() {
   384 	# Now remove installed build deps.
   385 	diff="$CACHE/installed.cook.diff"
   386 	if [ -s "$CACHE/installed.cook.diff" ]; then
   387 		deps=$(cat $diff | grep ^+[a-zA-Z0-9] | sed s/^+//)
   388 		nb=$(cat $diff | grep ^+[a-zA-Z0-9] | wc -l)
   389 		gettext "Build dependencies to remove:"; echo " $nb"
   390 		gettext "Removing:"
   391 		for dep in $deps
   392 		do
   393 			echo -n " $dep"
   394 			yes | tazpkg remove $dep >/dev/null
   395 		done
   396 		echo -e "\n"
   397 		# Keep the last diff for debug and info.
   398 		mv -f $CACHE/installed.cook.diff $CACHE/installed.diff
   399 	fi
   400 }
   402 # The main cook function.
   403 cookit() {
   404 	echo "Cook: $PACKAGE $VERSION"
   405 	separator
   406 	set_paths
   407 	[ "$QA" ] && receipt_quality
   408 	cd $pkgdir
   409 	rm -rf install taz source
   411 	# Disable -pipe if less than 512Mb free RAM.
   412 	free=$(free | fgrep '/+ buffers' | tr -s ' ' | cut -f 4 -d ' ')
   413 	if [ "$free" -lt 524288 ] && [ "$CFLAGS" != "${CFLAGS/-pipe}" ]; then
   414 			gettext -e "Disabling -pipe compile flag: $free RAM\n"
   415 			CFLAGS="${CFLAGS/-pipe}" && CFLAGS=$(echo "$CFLAGS" | tr -s ' ')
   416 			CXXFLAGS="${CXXFLAGS/-pipe}" && \
   417 				CXXFLAGS=$(echo "$CXXFLAGS" | tr -s ' ')
   418 	fi
   419 	unset free
   421 	# Export flags and path to be used by make
   422 	DESTDIR=$pkgdir/install
   423 	export DESTDIR MAKEFLAGS CFLAGS CXXFLAGS BUILD_HOST CONFIG_SITE
   424 	local LC_ALL=POSIX LANG=POSIX
   426 	# Check for build deps and handle implicit depends of *-dev packages
   427 	# (ex: libusb-dev :: libusb).
   428 	cd $INSTALLED && ls -1 > $CACHE/installed.list
   429 	[ "$DEPENDS" ] && gettext -e "Checking build dependencies...\n"
   430 	for dep in $BUILD_DEPENDS
   431 	do
   432 		implicit=${dep%-dev}
   433 		for i in $dep $implicit
   434 		do
   435 			if [ ! -f "$INSTALLED/$i/receipt" ]; then
   436 				# Try local package first.
   437 				vers=$(grep ^VERSION $WOK/$i/receipt | cut -d '"' -f 2)
   438 				if [ -f "$PKGS/$i-$vers.tazpkg" ]; then
   439 					gettext "Installing dep (pkg/local):"; echo " $i"
   440 					cd $PKGS && tazpkg install $i-$vers.tazpkg >/dev/null
   441 				else
   442 					gettext "Installing dep (web/cache):"; echo " $i"
   443 					tazpkg get-install $i >/dev/null
   444 				fi
   445 			fi
   446 		done
   447 	done
   448 	cd $INSTALLED && ls -1 > $CACHE/installed.cook && cd $CACHE
   450 	# If a cook failed deps are not removed since we exit 1.
   451 	[ ! -s "installed.cook.diff" ] && \
   452 		busybox diff installed.list installed.cook > installed.cook.diff
   453 	deps=$(cat installed.cook.diff | grep ^+[a-zA-Z0-9] | wc -l)
   455 	# Get source tarball and make sure we have source dir named:
   456 	# $PACKAGE-$VERSION to be standard in receipts. Here we use tar.lzma
   457 	# tarball if it exists.
   458 	if [ "$WGET_URL" ] && [ ! -f "$SRC/$TARBALL" ]; then
   459 		if [ -f "$SRC/${SOURCE:-$PACKAGE}-$VERSION.tar.lzma" ]; then
   460 			TARBALL=${SOURCE:-$PACKAGE}-$VERSION.tar.lzma
   461 		else
   462 			get_source || exit 1
   463 		fi
   464 	fi
   465 	if [ ! "$WANTED" ] && [ "$TARBALL" ] && [ ! -d "$src" ]; then
   466 		mkdir -p $pkgdir/source/tmp && cd $pkgdir/source/tmp
   467 		extract_source || exit 1
   468 		# Some archives are not well done and don't extract to one dir (ex lzma).
   469 		files=$(ls | wc -l)
   470 		[ "$files" == 1 ] && mv * ../$PACKAGE-$VERSION
   471 		[ "$files" -gt 1 ]  && mkdir -p ../$PACKAGE-$VERSION && \
   472 			mv * ../$PACKAGE-$VERSION
   473 		cd .. && rm -rf tmp
   474 	fi
   476 	# Execute receipt rules.
   477 	if grep -q ^compile_rules $receipt; then
   478 		gettext -e "Executing: compile_rules\n"
   479 		[ -d "$src" ] && cd $src
   480 		compile_rules $@ || exit 1
   481 		# Stay compatible with _pkg
   482 		[ -d "$src/_pkg" ] && mv $src/_pkg $install
   483 		# QA: compile_rules success so valid.
   484 		mkdir -p $install
   485 	else
   486 		# QA: No compile_rules so no error, valid.
   487 		mkdir -p $install
   488 	fi
   489 	separator && echo ""
   490 }
   492 # Cook quality assurance.
   493 cookit_quality() {
   494 	if [ ! -d "$WOK/$pkg/install" ] && [ ! "$WANTED" ]; then
   495 		echo -e "ERROR: cook failed" | tee -a $LOGS/$pkg.log
   496 	fi
   497 	# ERROR can be echoed any time in cookit()
   498 	if fgrep -q ERROR: $LOGS/$pkg.log; then
   499 		debug_info | tee -a $LOGS/$pkg.log
   500 		rm -f $command && exit 1
   501 	fi
   502 }
   504 # Create the package. Wanted to use Tazpkg to create a tazpkg package at first,
   505 # but it doesn't handle EXTRAVERSION.
   506 packit() {
   507 	set_paths
   508 	echo "Pack: $PACKAGE $VERSION"
   509 	separator
   510 	if grep -q ^genpkg_rules $receipt; then
   511 		gettext -e "Executing: genpkg_rules\n"
   512 		cd $pkgdir
   513 		mkdir -p $fs && genpkg_rules || echo -e \
   514 			"\nERROR: genpkg_rules failed\n" >> $LOGS/$pkg.log
   515 	fi
   517 	# First QA check to stop now if genpkg_rules failed.
   518 	if fgrep -q ERROR: $LOGS/$pkg.log; then
   519 		exit 1
   520 	fi
   522 	cd $taz
   523 	for file in receipt description.txt
   524 	do
   525 		[ ! -f "../$file" ] && continue
   526 		gettext "Copying"; echo -n " $file..."
   527 		cp -f ../$file $pack && chown 0.0 $pack/$file && status
   528 	done
   529 	copy_generic_files
   531 	# Create files.list with redirecting find output.
   532 	gettext "Creating the list of files..." && cd $fs
   533 	find . -type f -print > ../files.list
   534 	find . -type l -print >> ../files.list
   535 	cd .. && sed -i s/'^.'/''/ files.list
   536 	status
   538 	# Strip and stuff files.
   539 	strip_package
   541 	# Md5sum of files.
   542 	gettext "Creating md5sum of files..."
   543 	while read file; do
   544 		[ -L "fs$file" ] && continue
   545 		[ -f "fs$file" ] || continue
   546 		case "$file" in
   547 		/lib/modules/*/modules.*|*.pyc) continue;;
   548 		esac
   549 		md5sum "fs$file" | sed 's/  fs/  /'
   550 	done < files.list > md5sum
   551 	status
   552 	UNPACKED_SIZE=$(du -chs fs receipt files.list md5sum \
   553 		description.txt 2> /dev/null | awk \
   554 		'{ sz=$1 } END { print sz }')
   556 	# Build cpio archives.
   557 	gettext "Compressing the fs... "
   558 	find fs | cpio -o -H newc --quiet | lzma e fs.cpio.lzma -si
   559 	rm -rf fs
   560 	status
   561 	PACKED_SIZE=$(du -chs fs.cpio.lzma receipt files.list \
   562 		md5sum description.txt 2> /dev/null | awk \
   563 		'{ sz=$1 } END { print sz }')
   564 	gettext "Updating receipt sizes..."
   565 	sed -i s/^PACKED_SIZE.*$// receipt
   566 	sed -i s/^UNPACKED_SIZE.*$// receipt
   567 	sed -i "s/^PACKAGE=/PACKED_SIZE=\"$PACKED_SIZE\"\nUNPACKED_SIZE=\"$UNPACKED_SIZE\"\nPACKAGE=/" receipt
   568 	status
   570 	# Set extra version.
   571 	if [ "$EXTRAVERSION" ]; then
   572 		gettext "Updating receipt EXTRAVERSION: "; echo -n "$EXTRAVERSION"
   573 		sed -i s/^EXTRAVERSION.*$// receipt
   574 		sed -i "s/^VERSION=/EXTRAVERSION=\"$EXTRAVERSION\"\nVERSION=/" receipt
   575 		status
   576 	fi
   578 	# Compress.
   579 	gettext "Creating full cpio archive... "
   580 	find . -print | cpio -o -H newc --quiet > \
   581 		../$PACKAGE-${VERSION}${EXTRAVERSION}.tazpkg
   582 	status
   583 	gettext "Restoring original package tree... "
   584 	unlzma -c fs.cpio.lzma | cpio -idm --quiet
   585 	status
   586 	rm fs.cpio.lzma && cd ..
   588 	# QA and give info.
   589 	tazpkg=$(ls *.tazpkg)
   590 	packit_quality
   591 	separator && gettext "Package:"; echo -e " $tazpkg\n"
   592 }
   594 # Verify package quality and consistency.
   595 packit_quality() {
   596 	#gettext "QA: Checking for broken link..."
   597 	#link=$(find $fs/usr -type l -follow)
   598 	#[ "$link" ] && echo -e "\nERROR: broken link in filesystem"
   599 	#status
   601 	# Exit if any error found in log file.
   602 	if fgrep -q ERROR: $LOGS/$pkg.log; then
   603 		rm -f $command && exit 1
   604 	fi
   606 	gettext "QA: Checking for empty package..."
   607 	files=$(cat $WOK/$pkg/taz/$pkg-*/files.list | wc -l)
   608 	if [ "$files" -lt 0 ] && [ "$CATEGORY" != "meta" ]; then
   609 		echo -e "\nERROR: empty package"
   610 		rm -f $command && exit 1
   611 	else
   612 		# Ls sort by name so the first file is the one we want.
   613 		old=$(ls $PKGS/$pkg-*.tazpkg 2>/dev/null | head -n 1)
   614 		status
   615 		if [ -f "$old" ]; then
   616 			echo -n "Removing old: $(basename $old)"
   617 			rm -f $old && status
   618 		fi
   619 		mv -f $pkgdir/taz/$pkg-*.tazpkg $PKGS
   620 		sed -i /^${pkg}$/d $broken
   621 	fi
   622 }
   624 #
   625 # Commands
   626 #
   628 case "$1" in
   629 	usage|help|-u|-h)
   630 		 usage ;;
   631 	list-wok)
   632 		gettext -e "\nList of packages in:"; echo " $WOK"
   633 		separator
   634 		cd $WOK && ls -1
   635 		separator
   636 		echo -n "Packages: " && ls | wc -l
   637 		echo "" ;;
   638 	search)
   639 		# Just a simple search function, we dont need more actually.
   640 		query="$2"
   641 		gettext -e "\nSearch results for:"; echo " $query"
   642 		separator
   643 		cd $WOK && ls -1 | grep "$query"
   644 		separator && echo "" ;;
   645 	setup)
   646 		# Setup a build environment
   647 		check_root
   648 		echo "Cook: setting up the environment" | log
   649 		gettext -e "\nSetting up your environment\n"
   650 		separator && cd $SLITAZ
   651 		init_db_files
   652 		gettext -e "Checking for packages to install...\n"
   653 		for pkg in $SETUP_PKGS
   654 		do
   655 			[ ! -f "$INSTALLED/$pkg/receipt" ] && tazpkg get-install $pkg
   656 		done
   658 		# Handle --options
   659 		case "$2" in
   660 			--wok|-w)
   661 				[ ! -f "$INSTALLED/mercurial/receipt" ] && \
   662 					tazpkg get-install mercurial
   663 				[ -d "$WOK" ] && echo -e "A wok already exists.\n" && exit 1
   664 				hg clone $HG_URL ;;
   665 		esac
   667 		# SliTaz group and permissions
   668 		if ! grep -q ^slitaz /etc/group; then
   669 			gettext -e "Adding group: slitaz\n"
   670 			addgroup slitaz
   671 		fi
   672 		gettext -e "Setting permissions for slitaz group...\n"
   673 		chown -R root.slitaz $SLITAZ
   674 		chmod -R g+w $SLITAZ
   675 		separator
   676 		gettext -e "All done, ready to cook packages :-)\n\n" ;;
   677 	test)
   678 		# Test a cook environment.
   679 		echo "Cook test: testing the cook environment" | log
   680 		[ ! -d "$WOK" ] && exit 1
   681 		[ ! -d "$WOK/cooktest" ] && cp -r $DATA/cooktest $WOK
   682 		cook cooktest ;;
   683 	new)
   684 		# Create the package folder and an empty receipt.
   685 		pkg="$2"
   686 		[ "$pkg" ] || usage
   687 		echo ""
   688 		if [ -d "$WOK/$pkg" ]; then
   689 			echo -n  "$pkg " && gettext "package already exists."
   690 			echo -e "\n" && exit 1
   691 		fi
   692 		gettext "Creating"; echo -n " $WOK/$pkg"
   693 		mkdir $WOK/$pkg && cd $WOK/$pkg && status
   694 		gettext "Preparing the package receipt..."
   695 		cp $DATA/receipt .
   696 		sed -i s"/^PACKAGE=.*/PACKAGE=\"$pkg\"/" receipt
   697 		status && echo "" ;;
   698 	list)
   699 		# Cook a list of packages (better use the Cooker since it will order
   700 		# packages before executing cook).
   701 		check_root
   702 		[ -z "$2" ] && gettext -e "\nNo list in argument.\n\n" && exit 1
   703 		[ ! -f "$2" ] && gettext -e "\nNo list found:" && \
   704 			echo -e " $2\n" && exit 1
   705 		echo "Cook list starting: $2" | log
   706 		for pkg in $(cat $2)
   707 		do
   708 			cook $pkg || broken
   709 		done ;;
   710 	clean-wok)
   711 		check_root
   712 		gettext -e "\nCleaning all packages files..."
   713 		rm -rf $WOK/*/taz $WOK/*/install $WOK/*/source
   714 		status && echo "" ;;
   715 	clean-src)
   716 		check_root
   717 		gettext -e "\nCleaning all packages sources..."
   718 		rm -rf $WOK/*/source
   719 		status && echo "" ;;
   720 	pkglist)
   721 		# Create suitable packages list for TazPKG and only for built packages.
   722 		[ "$2" ] && PKGS="$2"
   723 		[ ! -d "$PKGS" ] && \
   724 			gettext -e "\nPackages directory doesn't exist\n\n" && exit 1
   725 		echo "cook:pkglist" > $command
   726 		echo "Cook pkglist: Creating all packages lists" | log
   727 		gettext -e "\nCreating lists for:"; echo " $PKGS"
   728 		separator
   729 		cd $PKGS
   730 		rm -f packages.* files.*
   731 		gettext -e "Creating: packages.list\n"
   732 		ls -1 *.tazpkg | sed s'/.tazpkg//' > $PKGS/packages.list
   733 		gettext -e "Creating: packages.md5\n"
   734 		md5sum *.tazpkg > $PKGS/packages.md5
   735 		gettext -e "Creating: packages.desc\n"
   736 		gettext -e "Creating: packages.equiv\n"
   737 		cd $WOK
   738 		for pkg in *
   739 		do
   740 			unset_receipt
   741 			. $pkg/receipt
   742 			# packages.desc lets us search easily in DB
   743 			if [ -f "$PKGS/$PACKAGE-${VERSION}${EXTRAVERSION}.tazpkg" ]; then
   744 				cat >> $PKGS/packages.desc << EOT
   745 $PACKAGE | $VERSION$EXTRAVERSION | $SHORT_DESC | $CATEGORY | $WEB_SITE
   746 EOT
   747 				# Packages.equiv is used by tazpkg install to check depends.
   748 				for i in $PROVIDE; do
   749 					DEST=""
   750 					echo $i | fgrep -q : && DEST="${i#*:}:"
   751 					if grep -qs ^${i%:*}= $PKGS/packages.equiv; then
   752 						sed -i "s/^${i%:*}=/${i%:*}=$DEST$PACKAGE /" \
   753 							$PKGS/packages.equiv
   754 					else
   755 						echo "${i%:*}=$DEST$PACKAGE" >> $PKGS/packages.equiv
   756 					fi
   757 				done
   758 			fi
   759 		done
   760 		cd $PKGS
   762 		# packages.txt (redundancy list, all info is in pkgs desc).
   763 		touch packages.txt
   765 		# files.list.lzma
   766 		gettext -e "Creating: files.list.lzma\n"
   767 		touch files.list
   768 		lzma e files.list files.list.lzma
   770 		separator
   771 		nb=$(ls $PKGS/*.tazpkg | wc -l)
   772 		echo -e "Packages: $nb\n"
   773 		rm -f $command ;;
   774 	*)
   775 		# Just cook and generate a package.
   776 		check_root
   777 		time=$(date +%s)
   778 		pkg="$1"
   779 		[ -z "$pkg" ] && usage
   780 		receipt="$WOK/$pkg/receipt"
   781 		check_pkg_in_wok && echo ""
   783 		# Display and log info if cook process stopped.
   784 		trap 'gettext -e "\n\nCook stopped: control-C\n\n" | \
   785 			tee -a $LOGS/$pkg.log' INT
   787 		# Skip blocked, 3 lines also for the Cooker.
   788 		if grep -q "^$pkg$" $blocked && [ "$2" != "--unblock" ]; then
   789 			gettext -e "Blocked package:"; echo -e " $pkg\n" && exit 0
   790 		fi
   792 		# Log and source receipt.
   793 		echo "Cook started for: <a href='cooker.cgi?pkg=$pkg'>$pkg</a>" | log
   794 		echo "cook:$pkg" > $command
   795 		unset inst
   796 		unset_receipt
   797 		. $receipt
   799 		# Handle --options
   800 		case "$2" in
   801 			--clean|-c)
   802 				gettext -e "Cleaning:"; echo -n " $pkg"
   803 				cd $WOK/$pkg && rm -rf install taz source
   804 				status && echo "" && exit 0 ;;
   805 			--install|-i)
   806 				inst='yes' ;;
   807 			--getsrc|-gs)
   808 				gettext "Getting source for:"; echo " $pkg"
   809 				separator && get_source
   810 				echo -e "Tarball: $SRC/$TARBALL\n" && exit 0 ;;
   811 			--block|-b)
   812 				gettext "Blocking:"; echo -n " $pkg"
   813 				[ $(grep "^$pkg$" $blocked) ] || echo "$pkg" >> $blocked
   814 				status && echo "" && exit 0 ;;
   815 			--unblock|-ub)
   816 				gettext "Unblocking:"; echo -n " $pkg"
   817 				sed -i "/^${pkg}$/"d $blocked
   818 				status && echo "" && exit 0 ;;
   819 		esac
   821 		# Check if wanted is built now so we have separate log files.
   822 		if [ "$WANTED" ] && [ ! -d "$WOK/$WANTED/install" ]; then
   823 			if ! grep -q "^$WANTED$" $broken; then
   824 				cook "$WANTED"
   825 			fi
   826 		fi
   828 		# Cook and pack or exit on error and log everything.
   829 		cookit $@ 2>&1 | tee $LOGS/$pkg.log
   830 		remove_deps | tee -a $LOGS/$pkg.log
   831 		cookit_quality
   832 		packit 2>&1 | tee -a $LOGS/$pkg.log
   833 		clean_log
   835 		# Exit if any error in packing.
   836 		if grep -q ^ERROR $LOGS/$pkg.log; then
   837 			debug_info | tee -a $LOGS/$pkg.log
   838 			rm -f $command && exit 1
   839 		fi
   841 		# Time and summary
   842 		time=$(($(date +%s) - $time))
   843 		summary | tee -a $LOGS/$pkg.log
   844 		echo ""
   846 		# Install package if requested
   847 		if [ "$inst" ]; then
   848 			if [ -f "$PKGS/$PACKAGE-${VERSION}${EXTRAVERSION}.tazpkg" ]; then
   849 				cd $PKGS && tazpkg install \
   850 					$PACKAGE-${VERSION}${EXTRAVERSION}.tazpkg --forced
   851 			else
   852 				gettext -e "Unable to install package, build has failed.\n\n"
   853 				exit 1
   854 			fi
   855 		fi
   856 		# Finally we DONT WANT to build the *-dev or packages with WANTED="$pkg"
   857 		# You want automation: use the Cooker Build Bot.
   858 		#[ -d "$WOK/$pkg-dev" ] && cook $pkg-dev
   859 		rm -f $command ;;
   860 esac
   862 exit 0