cookutils rev 912

cook: remake copy_generic_files()/copy_generic_stuff() logic; change build dep installation (AUTO_COOK isn't work now) with tazpkg cookmode; improve mk_pkg_receipt(), copy(); update 'cook package --pack'; add docs about copy(); lighttpd/index.cgi: summary on unpackaged files; tiny edits on lighttpd/cooker.css and modules/compressor.
author Aleksej Bobylev <al.bobylev@gmail.com>
date Mon Jun 05 15:59:11 2017 +0300 (2017-06-05)
parents 4402dabf5734
children 1e4e278b2285
files cook doc/receipts-v2.md lighttpd/cooker.css lighttpd/index.cgi modules/compressor
line diff
     1.1 --- a/cook	Thu Jun 01 19:27:13 2017 +0100
     1.2 +++ b/cook	Mon Jun 05 15:59:11 2017 +0300
     1.3 @@ -301,7 +301,7 @@
     1.4  		*.tar.lzma)             tar   -xaf    $SRC/$TARBALL ;;
     1.5  		*.tar.lz|*.tlz)         lzip  -d    < $SRC/$TARBALL | tar -xf - 2>/dev/null ;;
     1.6  		*.tar)                  tar   -xf     $SRC/$TARBALL ;;
     1.7 -		*.zip|*.xpi)            unzip -o      $SRC/$TARBALL 2>/dev/null ;;
     1.8 +		*.zip|*.xpi)            unzip -o      $SRC/$TARBALL 2>/dev/null >&2;;
     1.9  		*.xz)                   unxz  -c      $SRC/$TARBALL | tar -xf - || \
    1.10  		                        tar   -xf     $SRC/$TARBALL 2>/dev/null;;
    1.11  		*.7z)                   7zr    x      $SRC/$TARBALL 2>/dev/null >&2 ;;
    1.12 @@ -352,7 +352,7 @@
    1.13  	_ 'Host arch   : %s' "$ARCH"
    1.14  
    1.15  	separator -
    1.16 -	_ ' # : Packed : Compressed : Files : Package name'
    1.17 +	_ ' # :  Packed : Compressed : Files : Package name'
    1.18  	separator -
    1.19  	pkgi=1
    1.20  	for i in $PACKAGE $SPLIT; do
    1.21 @@ -360,7 +360,7 @@
    1.22  		pkgname="$i-$VERSION.tazpkg"
    1.23  		size=$(ls -lh $PKGS/$pkgname | awk '{print $5}')
    1.24  		files=$(wc -l < $WOK/$pkg/taz/$i-$VERSION/files.list)
    1.25 -		printf "%2d : %6s : %10s : %5s : %s\n" "$pkgi" "$fs" "$size" "$files" "$pkgname"
    1.26 +		printf "%2d : %7s : %10s : %5s : %s\n" "$pkgi" "$fs" "$size" "$files" "$pkgname"
    1.27  		pkgi=$((pkgi + 1))
    1.28  	done
    1.29  	separator
    1.30 @@ -406,17 +406,22 @@
    1.31  }
    1.32  
    1.33  
    1.34 -# Copy all generic files (locale, pixmaps, .desktop). We use standard paths,
    1.35 -# so some packages need to copy these files with the receipt and genpkg_rules.
    1.36 +# Copy all generic files (locale, pixmaps, .desktop) from $install to $fs.
    1.37 +# We use standard paths, so some packages need to copy these files with the
    1.38 +# receipt and genpkg_rules.
    1.39 +# This function executes inside the packaging process, before compressor call.
    1.40  
    1.41  copy_generic_files() {
    1.42 +	# Proceed only for "main" package (for v2), and for any packages (v1)
    1.43 +	[ "$pkg" == "$PACKAGE" ] || return 0
    1.44 +
    1.45  	# $LOCALE is set in cook.conf
    1.46  	if [ -n "$LOCALE" -a -z "$WANTED" ]; then
    1.47  		if [ -d "$install/usr/share/locale" ]; then
    1.48 -			mkdir -p $fs/usr/share/locale
    1.49 +			mkdir -p "$fs/usr/share/locale"
    1.50  			for i in $LOCALE; do
    1.51  				if [ -d  "$install/usr/share/locale/$i" ]; then
    1.52 -					scopy $install/usr/share/locale/$i $fs/usr/share/locale
    1.53 +					cp -a $install/usr/share/locale/$i $fs/usr/share/locale
    1.54  				fi
    1.55  			done
    1.56  		fi
    1.57 @@ -425,43 +430,49 @@
    1.58  	# Generic pixmaps copy can be disabled with COOKOPTS="!pixmaps" (or GENERIC_PIXMAPS="no")
    1.59  	if [ "${COOKOPTS/!pixmaps/}" == "$COOKOPTS" -a "$GENERIC_PIXMAPS" != 'no' ]; then
    1.60  		if [ -d "$install/usr/share/pixmaps" ]; then
    1.61 -			mkdir -p $fs/usr/share/pixmaps
    1.62 +			mkdir -p "$fs/usr/share/pixmaps"
    1.63  			for i in png xpm; do
    1.64  				[ -f "$install/usr/share/pixmaps/$PACKAGE.$i" ] &&
    1.65 -				scopy $install/usr/share/pixmaps/$PACKAGE.$i $fs/usr/share/pixmaps
    1.66 +				cp -a $install/usr/share/pixmaps/$PACKAGE.$i $fs/usr/share/pixmaps
    1.67  			done
    1.68  		fi
    1.69 -
    1.70 -		# Custom or homemade PNG pixmap can be in stuff.
    1.71 -		if [ -f "$stuff/$PACKAGE.png" ]; then
    1.72 -			mkdir -p $fs/usr/share/pixmaps
    1.73 -			scopy $stuff/$PACKAGE.png $fs/usr/share/pixmaps
    1.74 -		fi
    1.75  	fi
    1.76  
    1.77  	# Desktop entry (.desktop).
    1.78  	# Generic desktop entry copy can be disabled with COOKOPTS="!menus" (or GENERIC_MENUS="no")
    1.79  	if [ "${COOKOPTS/!menus/}" == "$COOKOPTS" -a "$GENERIC_MENUS" != 'no' ]; then
    1.80 -		if [ -d "$install/usr/share/applications" ] && [ -z "$WANTED" ]; then
    1.81 -			mkdir -p $fs/usr/share
    1.82 -			scopy $install/usr/share/applications $fs/usr/share
    1.83 +		if [ -d "$install/usr/share/applications" -a -z "$WANTED" ]; then
    1.84 +			mkdir -p "$fs/usr/share"
    1.85 +			cp -a $install/usr/share/applications $fs/usr/share
    1.86  		fi
    1.87  	fi
    1.88 +}
    1.89 +
    1.90 +
    1.91 +# Copy pixmaps, desktop files and licenses from $stuff to $install.
    1.92 +# This function executes after the main compile_rules() is done.
    1.93 +
    1.94 +copy_generic_stuff() {
    1.95 +	# Custom or homemade PNG pixmap can be in stuff.
    1.96 +	if [ -f "$stuff/$PACKAGE.png" ]; then
    1.97 +		mkdir -p $install/usr/share/pixmaps
    1.98 +		cp $stuff/$PACKAGE.png $install/usr/share/pixmaps
    1.99 +	fi
   1.100  
   1.101  	# Homemade desktop file(s) can be in stuff.
   1.102  	if [ -d "$stuff/applications" ]; then
   1.103 -		mkdir -p $fs/usr/share
   1.104 -		scopy $stuff/applications $fs/usr/share
   1.105 +		mkdir -p $install/usr/share
   1.106 +		cp $stuff/applications $install/usr/share
   1.107  	fi
   1.108  	if [ -f "$stuff/$PACKAGE.desktop" ]; then
   1.109 -		mkdir -p $fs/usr/share/applications
   1.110 -		scopy $stuff/$PACKAGE.desktop $fs/usr/share/applications
   1.111 +		mkdir -p $install/usr/share/applications
   1.112 +		cp $stuff/$PACKAGE.desktop $install/usr/share/applications
   1.113  	fi
   1.114  
   1.115  	# Add custom licenses
   1.116  	if [ -d "$stuff/licenses" ]; then
   1.117 -		mkdir -p $fs/usr/share/licenses
   1.118 -		scopy $stuff/licenses $fs/usr/share/licenses/$PACKAGE
   1.119 +		mkdir -p $install/usr/share/licenses
   1.120 +		cp $stuff/licenses $install/usr/share/licenses/$PACKAGE
   1.121  	fi
   1.122  }
   1.123  
   1.124 @@ -532,9 +543,12 @@
   1.125  
   1.126  	while read i; do
   1.127  		[ -f "$src/done.$i" ] && continue
   1.128 -		patch -p1 -i $stuff/patches/$i
   1.129 +		newline
   1.130 +		_ 'Applying patch %s' "$i"
   1.131 +		patch -p1 -i $stuff/patches/$i | sed 's|^|  |'
   1.132  		touch $src/done.$i
   1.133  	done < $stuff/patches/series
   1.134 +	newline
   1.135  }
   1.136  
   1.137  
   1.138 @@ -627,89 +641,83 @@
   1.139  
   1.140  	# Check for build deps and handle implicit depends of *-dev packages
   1.141  	# (ex: libusb-dev :: libusb).
   1.142 -	rm -f $CACHE/installed.local $CACHE/installed.web $CACHE/missing.dep
   1.143 -	touch $CACHE/installed.local $CACHE/installed.web
   1.144 +#	rm -f $CACHE/installed.local $CACHE/installed.web $CACHE/missing.dep
   1.145 +#	touch $CACHE/installed.local $CACHE/installed.web
   1.146  	[ -n "$BUILD_DEPENDS" ] && _ 'Checking build dependencies...'
   1.147  	[ -n "$root" ] && _ 'Using packages DB: %s' "$root$DB"
   1.148 -	for dep in $BUILD_DEPENDS; do
   1.149 -		implicit="${dep%-dev}"; [ "$implicit" == "$dep" ] && implicit=''
   1.150 -		for i in $dep $implicit; do
   1.151 -#			echo "i='$i'"
   1.152 -			# Check if package already installed
   1.153 -			[ -f "$root$INSTALLED/$i/receipt" ] && continue
   1.154  
   1.155 -			# Try local package first.
   1.156 -			namever=$(awk -F$'\t' -vpkg="$i" '{
   1.157 -				# if package-name or provided-package-name matched
   1.158 -				if (index(" " $1 " " $10 " ", " " pkg " ")) { printf("%s-%s", $1, $2); exit; }
   1.159 -			}' "$PKGS/packages.info")		# <namever> = <package_name>-<package_version>
   1.160 +	for action in check install; do
   1.161 +		for dep in $BUILD_DEPENDS; do
   1.162 +			implicit="${dep%-dev}"; [ "$implicit" == "$dep" ] && implicit=''
   1.163 +			for i in $dep $implicit; do
   1.164 +				# Skip if package already installed
   1.165 +				[ -f "$root$INSTALLED/$i/receipt" ] && continue
   1.166  
   1.167 -			debug "bdep: $i name-version: $namever"
   1.168 -
   1.169 -			# If local package available
   1.170 -			[ -f "$PKGS/$namever$arch.tazpkg" ] &&
   1.171 -				echo "$namever$arch.tazpkg" >> $CACHE/installed.local && continue
   1.172 -
   1.173 -			# If package exists in wok but not built
   1.174 -			[ -d "$WOK/$i" ] &&
   1.175 -				_ 'Missing dep (wok/pkg): %s' "$i $vers" &&
   1.176 -				echo $i >> $CACHE/missing.dep && continue
   1.177 -
   1.178 -			# If package available on the mirror
   1.179 -			[ -n "$(awk -F$'\t' -vi="$i" '$1==i{print $1}' "$root$DB/packages.info")" ] &&
   1.180 -				echo $i >> $CACHE/installed.web && continue
   1.181 -
   1.182 -			# Give up; skip error for implicit dependency: in some cases
   1.183 -			# implicit doesn't exist, ex: libboost-dev exists but not libboost.
   1.184 -			[ "$i" == "$dep" ] && die 'ERROR: unknown dep "%s"' "$i"
   1.185 +				case $action in
   1.186 +					check)
   1.187 +						# Search for local package or local provided-package
   1.188 +						name=$(awk -F$'\t' -vpkg="$i" '{
   1.189 +						if (index(" " $1 " " $10 " ", " " pkg " ")) {print $1; exit}
   1.190 +						}' "$PKGS/packages.info")
   1.191 +						if [ -z "$name" ]; then
   1.192 +							# Search for package in mirror
   1.193 +							name="$(awk -F$'\t' -vi="$i" '$1==i{print $1; exit}' "$root$DB/packages.info")"
   1.194 +							[ -z "$name" -a "$i" == "$dep" ] && die 'ERROR: unknown dep "%s"' "$i"
   1.195 +						fi
   1.196 +						;;
   1.197 +					install)
   1.198 +						tazpkg get-install $i --root=$root --local --quiet --cookmode || { broken; exit 1; }
   1.199 +						;;
   1.200 +				esac
   1.201 +			done
   1.202  		done
   1.203  	done
   1.204  
   1.205 -	# Get the list of installed packages
   1.206 -	cd $root$INSTALLED; ls -1 > $CACHE/installed.list
   1.207 -
   1.208 -	# Have we a missing build dep to cook?
   1.209 -	if [ -s "$CACHE/missing.dep" ] && [ -n "$AUTO_COOK" ]; then
   1.210 -		_ 'Auto cook config is set: %s' "$AUTO_COOK"
   1.211 -		cp -f $LOGS/$PACKAGE.log $LOGS/$PACKAGE.log.$$
   1.212 -		for i in $(uniq $CACHE/missing.dep); do
   1.213 -			(_ 'Building dep (wok/pkg)    : %s' "$i $vers") | \
   1.214 -				tee -a $LOGS/$PACKAGE.log.$$
   1.215 -			# programmers: next two messages are exact copy from remove_deps()
   1.216 -			togrep1=$(_n 'Build dependencies to remove:')
   1.217 -			togrep2=$(_n 'Removing:')
   1.218 -			cook $i || (_ "ERROR: can't cook dep \"%s\"" "$i" && newline && \
   1.219 -				fgrep $togrep1 $LOGS/$i.log && \
   1.220 -				fgrep $togrep2 $LOGS/$i.log && newline) | \
   1.221 -				tee -a $LOGS/$PACKAGE.log.$$ && break
   1.222 -		done
   1.223 -		rm -f $CACHE/missing.dep
   1.224 -		mv  $LOGS/$PACKAGE.log.$$ $LOGS/$PACKAGE.log
   1.225 -	fi
   1.226 -
   1.227 -	# QA: Exit on missing dep errors. We exit in both cases, if AUTO_COOK
   1.228 -	# is enabled and cook fails we have ERROR in log, if no auto cook we have
   1.229 -	# missing dep in cached file.
   1.230 -	lerror=$(_n 'ERROR')
   1.231 -	if fgrep -q ^$lerror $LOGS/$pkg.log || [ -s "$CACHE/missing.dep" ]; then
   1.232 -		[ -s "$CACHE/missing.dep" ] && nb=$(wc -l < $CACHE/missing.dep)
   1.233 -		_p 'ERROR: missing %d dependency' 'ERROR: missing %d dependencies' "$nb" "$nb"
   1.234 -		broken; exit 1
   1.235 -	fi
   1.236 -
   1.237 -	# Install local packages: package-version$arch
   1.238 -	cd $PKGS
   1.239 -	for i in $(uniq $CACHE/installed.local); do
   1.240 -		# _ 'Installing dep (pkg/local): %s' "$i"
   1.241 -		tazpkg install $i --root=$root --local --quiet --cookmode
   1.242 -	done
   1.243 -
   1.244 -	# Install web or cached packages (if mirror is set to $PKGS we only
   1.245 -	# use local packages).
   1.246 -	for i in $(uniq $CACHE/installed.web); do
   1.247 -		# _ 'Installing dep (web/cache): %s' "$i"
   1.248 -		tazpkg get-install $i --root=$root --local --quiet --cookmode
   1.249 -	done
   1.250 +#	# Get the list of installed packages
   1.251 +#	cd $root$INSTALLED; ls -1 > $CACHE/installed.list
   1.252 +#
   1.253 +#	# Have we a missing build dep to cook?
   1.254 +#	if [ -s "$CACHE/missing.dep" ] && [ -n "$AUTO_COOK" ]; then
   1.255 +#		_ 'Auto cook config is set: %s' "$AUTO_COOK"
   1.256 +#		cp -f $LOGS/$PACKAGE.log $LOGS/$PACKAGE.log.$$
   1.257 +#		for i in $(uniq $CACHE/missing.dep); do
   1.258 +#			(_ 'Building dep (wok/pkg)    : %s' "$i $vers") | \
   1.259 +#				tee -a $LOGS/$PACKAGE.log.$$
   1.260 +#			# programmers: next two messages are exact copy from remove_deps()
   1.261 +#			togrep1=$(_n 'Build dependencies to remove:')
   1.262 +#			togrep2=$(_n 'Removing:')
   1.263 +#			cook $i || (_ "ERROR: can't cook dep \"%s\"" "$i" && newline && \
   1.264 +#				fgrep $togrep1 $LOGS/$i.log && \
   1.265 +#				fgrep $togrep2 $LOGS/$i.log && newline) | \
   1.266 +#				tee -a $LOGS/$PACKAGE.log.$$ && break
   1.267 +#		done
   1.268 +#		rm -f $CACHE/missing.dep
   1.269 +#		mv  $LOGS/$PACKAGE.log.$$ $LOGS/$PACKAGE.log
   1.270 +#	fi
   1.271 +#
   1.272 +#	# QA: Exit on missing dep errors. We exit in both cases, if AUTO_COOK
   1.273 +#	# is enabled and cook fails we have ERROR in log, if no auto cook we have
   1.274 +#	# missing dep in cached file.
   1.275 +#	lerror=$(_n 'ERROR')
   1.276 +#	if fgrep -q ^$lerror $LOGS/$pkg.log || [ -s "$CACHE/missing.dep" ]; then
   1.277 +#		[ -s "$CACHE/missing.dep" ] && nb=$(wc -l < $CACHE/missing.dep)
   1.278 +#		_p 'ERROR: missing %d dependency' 'ERROR: missing %d dependencies' "$nb" "$nb"
   1.279 +#		broken; exit 1
   1.280 +#	fi
   1.281 +#
   1.282 +#	# Install local packages: package-version$arch
   1.283 +#	cd $PKGS
   1.284 +#	for i in $(uniq $CACHE/installed.local); do
   1.285 +#		# _ 'Installing dep (pkg/local): %s' "$i"
   1.286 +#		tazpkg install $i --root=$root --local --quiet --cookmode
   1.287 +#	done
   1.288 +#
   1.289 +#	# Install web or cached packages (if mirror is set to $PKGS we only
   1.290 +#	# use local packages).
   1.291 +#	for i in $(uniq $CACHE/installed.web); do
   1.292 +#		# _ 'Installing dep (web/cache): %s' "$i"
   1.293 +#		tazpkg get-install $i --root=$root --local --quiet --cookmode
   1.294 +#	done
   1.295  
   1.296  	update_installed_cook_diff
   1.297  
   1.298 @@ -775,6 +783,8 @@
   1.299  		mkdir -p $install
   1.300  	fi
   1.301  
   1.302 +	copy_generic_stuff
   1.303 +
   1.304  	# Actions to do after compiling the package
   1.305  	# Skip all for split packages (already done in main package)
   1.306  	if [ -z "$WANTED" ]; then
   1.307 @@ -824,15 +834,26 @@
   1.308  	[ "${signature:0:1}" == '#' ] || signature='# SliTaz package receipt.'
   1.309  
   1.310  	save_PACKAGE="$PACKAGE"; save_DEPENDS="$DEPENDS"; save_PROVIDE="$PROVIDE"
   1.311 +	save_SUGGESTED="$SUGGESTED"; save_TAZPANEL_DAEMON="$TAZPANEL_DAEMON"
   1.312  	unset_receipt
   1.313  	. "$orig_receipt"
   1.314  	PACKAGE="$save_PACKAGE"; DEPENDS="$save_DEPENDS"; PROVIDE="$save_PROVIDE"
   1.315 +	SUGGESTED="$save_SUGGESTED"; TAZPANEL_DAEMON="$save_TAZPANEL_DAEMON"
   1.316  
   1.317  	# Manage split packages
   1.318  	SPLIT=" $SPLIT "
   1.319  	if [ "$SPLIT" != '  ' -a "${SPLIT/ $PACKAGE /}" != "$SPLIT" ]; then
   1.320  		# For packages with empty $DEPENDS
   1.321 -		[ -n "$DEPENDS" ] || DEPENDS="$pkg"
   1.322 +		if [ -z "$DEPENDS" ]; then
   1.323 +			case $PACKAGE in
   1.324 +				*-dev)
   1.325 +					# main package and all the split packages but this *-dev itself
   1.326 +					DEPENDS=$(echo "$pkg $SPLIT " | sed "s| $PACKAGE | |; s| *$||") ;;
   1.327 +				*)
   1.328 +					# main package
   1.329 +					DEPENDS="$pkg" ;;
   1.330 +			esac
   1.331 +		fi
   1.332  
   1.333  		# Default $CAT
   1.334  		[ -z "$CAT" ] &&
   1.335 @@ -859,23 +880,24 @@
   1.336  EOF
   1.337  
   1.338  	# Optional variables
   1.339 -	[ -n "$TAGS" ]    && echo "TAGS=\"$TAGS\""
   1.340 -	[ -n "$DEPENDS" ] && echo "DEPENDS=\"$DEPENDS\"" | tr -ds '\t' ' '
   1.341 -	[ -n "$PROVIDE" ] && echo "PROVIDE=\"$PROVIDE\""
   1.342 -	[ -n "$CONFIG_FILES" ] && echo "CONFIG_FILES=\"$CONFIG_FILES\""
   1.343 +	[ -n "$TAGS" ]    && echo "TAGS=\"$TAGS\"" | tr -ds '\t' ' '
   1.344 +	[ -n "${DEPENDS# }" ] && echo "DEPENDS=\"$DEPENDS\"" | tr -ds '\t' ' '
   1.345 +	[ -n "$PROVIDE" ] && echo "PROVIDE=\"$PROVIDE\"" | tr -ds '\t' ' '
   1.346 +	[ -n "$CONFIG_FILES" ] && echo "CONFIG_FILES=\"$CONFIG_FILES\"" | tr -ds '\t' ' '
   1.347 +	[ -n "$DATABASE_FILES" ] && echo "DATABASE_FILES=\"$DATABASE_FILES\""
   1.348 +	[ -n "$TAZPANEL_DAEMON" ] && echo "TAZPANEL_DAEMON=\"$TAZPANEL_DAEMON\""
   1.349  
   1.350  	# Extract {pre,post}_{install,remove} functions;
   1.351 -	# post_install_gtk_() will be copied as post_install() for gtk+ package
   1.352 +	# post_install()      will be copied for both main and all the split packages
   1.353 +	# post_install_gtk_() will be copied as post_install() for gtk+ package only
   1.354  	#
   1.355  	# restricted name (gtk+ -> gtk_; acl-dev -> acl_dev)
   1.356  	rname=$(echo -n $PACKAGE | tr -c 'a-zA-Z0-9' '_')
   1.357  	for i in pre post; do
   1.358  		for j in install remove; do
   1.359 -			if grep -q "^${i}_${j}_$rname()" "$orig_receipt"; then
   1.360 -				echo
   1.361 -				sed "/^${i}_${j}_$rname()/,/^}/!d" "$orig_receipt" | \
   1.362 +			sed "/^${i}_${j}()/,/^}/!d" "$orig_receipt"
   1.363 +			sed "/^${i}_${j}_$rname()/,/^}/!d" "$orig_receipt" | \
   1.364  				sed "s|^${i}_${j}_$rname()|${i}_${j}()|"
   1.365 -			fi
   1.366  		done
   1.367  	done
   1.368  }
   1.369 @@ -907,6 +929,7 @@
   1.370  
   1.371  	# Check CONFIG_FILES
   1.372  	if [ -n "$CONFIG_FILES" ]; then
   1.373 +		unset IFS
   1.374  		for i in $CONFIG_FILES; do
   1.375  			if [ ! -e $fs$i ]; then
   1.376  				case $i in
   1.377 @@ -1059,7 +1082,7 @@
   1.378  	set_paths
   1.379  	if head -n1 "$pkgdir/receipt" | fgrep -q 'v2'; then
   1.380  		for i in $PACKAGE $SPLIT; do
   1.381 -			unset DEPENDS CAT CONFIG_FILES
   1.382 +			unset TAGS DEPENDS CAT CONFIG_FILES PROVIDE DATABASE_FILES TAZPANEL_DAEMON
   1.383  			packit $i
   1.384  		done
   1.385  	else
   1.386 @@ -1277,10 +1300,9 @@
   1.387  
   1.388  copy() {
   1.389  	action 'Copying folders and files...'
   1.390 -	cd $install
   1.391 -	local i j filelist=$(mktemp) tmplist=$(mktemp)
   1.392 +	local i j filelist=$(mktemp)
   1.393  	IFS=$'\n'
   1.394 -	find ! -type d | sed 's|\.||' > $filelist
   1.395 +	cd $install; find ! -type d | sed 's|\.||' > $filelist
   1.396  	for i in $@; do
   1.397  		case $i in
   1.398  			@std)
   1.399 @@ -1291,41 +1313,37 @@
   1.400  					/\/share\/man\//d; /\/share\/doc\//d; /\/share\/gtk-doc\//d; /\/share\/info\//d;
   1.401  					/\/share\/devhelp\//d; /\/share\/locale\//d;
   1.402  					/\/share\/bash-completion\//d; /\/lib\/systemd\//d;
   1.403 -					' $filelist > $tmplist
   1.404 -				while read j; do
   1.405 -					mkdir -p $fs$(dirname $j)
   1.406 -					scopy $install$j $fs$(dirname $j)
   1.407 -				done < $tmplist
   1.408 +					' $filelist
   1.409  				;;
   1.410  			@dev)
   1.411  				# Copy "developer files"
   1.412  				sed -n '/\.h$/p; /\.hxx$/p; /\.a$/p; /\.la$/p; /\.pc$/p; /bin\/.*-config$/p;
   1.413  					/\.m4$/p; /\.gir$/p; /\.typelib$/p; /\.vapi$/p; /\.deps$/p; /\.cmake$/p;
   1.414  					/\/include\//p;
   1.415 -					' $filelist | \
   1.416 -				while read j; do
   1.417 -					mkdir -p $fs$(dirname $j)
   1.418 -					scopy $install$j $fs$(dirname $j)
   1.419 -				done
   1.420 +					' $filelist
   1.421  				;;
   1.422  			*/)
   1.423 -				# Copy specified folders
   1.424 -				for j in $(find . -name ${i%/} -type d); do
   1.425 -					mkdir -p $fs$(dirname ${j#.})
   1.426 -					cp -a $j $fs$(dirname ${j#.})
   1.427 -				done
   1.428 +				# Copy specified folders.
   1.429 +				i="${i%/}"
   1.430 +				find -type d -path "*/${i#/}" | sed 's|^.||'
   1.431  				;;
   1.432  			*)
   1.433 -				# Copy specified files
   1.434 -				for j in $(find . -name $i ! -type d); do
   1.435 -					mkdir -p $fs$(dirname ${j#.})
   1.436 -					scopy $j $fs$(dirname ${j#.})
   1.437 -				done
   1.438 +				# Copy specified files.
   1.439 +				find ! -type d -path "*/${i#/}" | sed 's|^.||'
   1.440  				;;
   1.441 -		esac
   1.442 +		esac | sort -u | \
   1.443 +		while read j; do
   1.444 +			mkdir -p $fs$(dirname "$j")
   1.445 +			if [ -d "$install$j" ]; then
   1.446 +				cp -a "$install$j" $fs$(dirname "$j")
   1.447 +			else
   1.448 +				scopy "$install$j" $fs$(dirname "$j")
   1.449 +			fi
   1.450 +		done
   1.451  	done
   1.452  	cd - >/dev/null
   1.453 -	rm $filelist $tmplist
   1.454 +	unset IFS
   1.455 +	rm $filelist
   1.456  	status
   1.457  }
   1.458  
   1.459 @@ -1760,7 +1778,7 @@
   1.460  				[ -d $WOK/$pkg/taz ] || die 'Need to build "%s"' "$pkg"
   1.461  				rm -rf $WOK/$pkg/taz
   1.462  				[ -f $LOGS/$pkg-pack.log ] && rm -rf $LOGS/$pkg-pack.log
   1.463 -				packit 2>&1 | tee -a $LOGS/$pkg-pack.log
   1.464 +				packall 2>&1 | tee -a $LOGS/$pkg-pack.log
   1.465  				clean_log
   1.466  				rm -f $command
   1.467  				exit 0 ;;
     2.1 --- a/doc/receipts-v2.md	Thu Jun 01 19:27:13 2017 +0100
     2.2 +++ b/doc/receipts-v2.md	Mon Jun 05 15:59:11 2017 +0300
     2.3 @@ -89,3 +89,67 @@
     2.4  
     2.5      post_install_coreutils_disk()
     2.6  
     2.7 +
     2.8 +Function `copy()`
     2.9 +-----------------
    2.10 +
    2.11 +It's the flexible tool allowing you to copy files and folders from `$install` to
    2.12 +`$fs` using patterns. All files are copied with the folder structure preserved:
    2.13 +
    2.14 +    $install/my/folder/       ->   $fs/my/folder/
    2.15 +    $install/my/system/file   ->   $fs/my/system/file
    2.16 +
    2.17 +Now `copy()` understands 4 main forms of patterns:
    2.18 +
    2.19 +  * `@std`    - all the "standard" files;
    2.20 +  * `@dev`    - all the "developer" files;
    2.21 +  * `folder/` - append folder name in question by slash;
    2.22 +  * `file`    - file name without the slash in the end.
    2.23 +
    2.24 +Both patterns `@std` and `@dev` are meta-patterns making the most common actions
    2.25 +extremely simple.
    2.26 +
    2.27 +In the `folder/` and `file` forms of the patterns you can use the asterisk (`*`)
    2.28 +symbol meaning any number of any characters.
    2.29 +
    2.30 +Some examples (executed on the chroot with the "busybox" package installed):
    2.31 +
    2.32 +```
    2.33 +  Pattern  | Result
    2.34 +===========|====================================================================
    2.35 +   bin/    | /bin
    2.36 +           | /usr/bin
    2.37 +-----------|--------------------------------------------------------------------
    2.38 +  *bin/    | /bin
    2.39 +           | /sbin
    2.40 +           | /usr/bin
    2.41 +           | /usr/sbin
    2.42 +           | /var/www/cgi-bin
    2.43 +-----------|--------------------------------------------------------------------
    2.44 + /usr/bin/ | /usr/bin
    2.45 +-----------|--------------------------------------------------------------------
    2.46 +  usr/bin/ | /usr/bin
    2.47 +-----------|--------------------------------------------------------------------
    2.48 +    r/bin/ |
    2.49 +===========|====================================================================
    2.50 +    cat    | /bin/cat
    2.51 +-----------|--------------------------------------------------------------------
    2.52 +   *.sh    | /lib/libtaz.sh
    2.53 +           | /sbin/mktazdevs.sh
    2.54 +           | /usr/bin/gettext.sh
    2.55 +           | /usr/bin/httpd_helper.sh
    2.56 +           | /usr/lib/slitaz/httphelper.sh
    2.57 +           | /usr/lib/slitaz/libpkg.sh
    2.58 +           | /var/www/cgi-bin/cgi-env.sh
    2.59 +-----------|--------------------------------------------------------------------
    2.60 +    pt*    | /dev/pts
    2.61 +           | /usr/share/locale/pt_BR
    2.62 +           | /usr/share/locale/pt_BR/LC_MESSAGES
    2.63 +-----------|--------------------------------------------------------------------
    2.64 + /bin/*.sh | /usr/bin/gettext.sh
    2.65 +           | /usr/bin/httpd_helper.sh
    2.66 +-----------|--------------------------------------------------------------------
    2.67 + /lib/*.sh | /lib/libtaz.sh
    2.68 +           | /usr/lib/slitaz/httphelper.sh
    2.69 +           | /usr/lib/slitaz/libpkg.sh
    2.70 +```
     3.1 --- a/lighttpd/cooker.css	Thu Jun 01 19:27:13 2017 +0100
     3.2 +++ b/lighttpd/cooker.css	Mon Jun 05 15:59:11 2017 +0300
     3.3 @@ -174,6 +174,9 @@
     3.4  .log i  { font-style: normal;    color: green; }
     3.5  .log em { font-style: normal;    background-color: lightsteelblue; font-weight: bold; display: inline-block; width: 100%; }
     3.6  
     3.7 +.catman b  { color: navy; }
     3.8 +.catman u  { text-decoration: none; color: green; }
     3.9 +
    3.10  
    3.11  
    3.12  /* Buttons */
    3.13 @@ -327,7 +330,8 @@
    3.14  .pkgslist td:nth-child(1), .pkgslist td:nth-child(2), .pkgslist td:nth-child(3), .pkgslist td:nth-child(4) {
    3.15  	white-space: nowrap; width: 1rem; text-align: right;
    3.16  }
    3.17 -
    3.18 +.summary th, .summary td { white-space: nowrap; width: 1rem; text-align: center; }
    3.19 +.summary th:last-child, .summary td:last-child { width: unset; }
    3.20  
    3.21  
    3.22  div.list td, div.list th { padding: 5px 2px; }
     4.1 --- a/lighttpd/index.cgi	Thu Jun 01 19:27:13 2017 +0100
     4.2 +++ b/lighttpd/index.cgi	Mon Jun 05 15:59:11 2017 +0300
     4.3 @@ -458,9 +458,11 @@
     4.4  				-e 's#Success$#<i>Success</i>#' \
     4.5  				-e 's#\([^a-z]\)ok$#\1<i>ok</i>#' \
     4.6  				-e 's#\([^a-z]\)yes$#\1<i>yes</i>#' \
     4.7 +				-e 's#\([^a-z]\)ON$#\1<i>ON</i>#' \
     4.8  				-e 's#\([^a-z]\)no$#\1<u>no</u>#' \
     4.9  				-e 's#\([^a-z]\)none$#\1<u>none</u>#' \
    4.10  				-e 's#\([^a-z]\)false$#\1<u>false</u>#' \
    4.11 +				-e 's#\([^a-z]\)OFF$#\1<u>OFF</u>#' \
    4.12  				-e 's#\(^checking .*\.\.\. \)\(.*\)$#\1<i>\2</i>#' \
    4.13  				\
    4.14  				-e 's#\( \[Y[nm/]\?\] n\)$# <u>\1</u>#' \
    4.15 @@ -1018,14 +1020,20 @@
    4.16  
    4.17  			size=$(du -hs $dir | awk '{ sub(/\.0/, ""); print $1 }')
    4.18  
    4.19 -			echo "<section><h3>Files of package “$namever” ($size):</h3>"
    4.20 -			echo -en '<pre class="files">\n<span class="underline">permissions·lnk·user    ·'
    4.21 -			echo -en 'group   ·     size·date &amp; time ·file name\n</span>'
    4.22 -			find $dir -not -type d -print0 | sort -z | xargs -0 ls -ld --color=always | \
    4.23 -			syntax_highlighter files | \
    4.24 -			sed "s|\([^>]*\)>/.*/fs\([^<]*\)\(<.*\)$|\1 href='$base/$indir/browse/taz/$p-$ver/fs\2'>\2\3|" | \
    4.25 -			awk 'BEGIN { FS="\""; }
    4.26 -				{ gsub("+", "%2B", $2); print; }'
    4.27 +			echo "<section><h3>Files of package “$namever” (${size:-empty}):</h3>"
    4.28 +			echo '<pre class="files">'
    4.29 +			if [ -s "$wok/$indir/taz/$p-$ver/files.list" ]; then
    4.30 +				echo -n '<span class="underline">permissions·lnk·user    ·'
    4.31 +				echo -en 'group   ·     size·date &amp; time ·file name\n</span>'
    4.32 +				cd $dir
    4.33 +				find . -not -type d -print0 | sort -z | xargs -0 ls -ld --color=always | \
    4.34 +				syntax_highlighter files | \
    4.35 +				sed "s|\([^>]*\)>\.\([^<]*\)\(<.*\)$|\1 href='$base/$indir/browse/taz/$p-$ver/fs\2'>\2\3|" | \
    4.36 +				awk 'BEGIN { FS="\""; }
    4.37 +					{ gsub("+", "%2B", $2); print; }'
    4.38 +			else
    4.39 +				echo 'No files'
    4.40 +			fi
    4.41  			echo '</pre></section>'
    4.42  			cat $wok/$indir/taz/$p-$ver/files.list >> $packaged
    4.43  		done
    4.44 @@ -1042,21 +1050,45 @@
    4.45  		all_files=$(mktemp)
    4.46  		cd $wok/$main/install; find ! -type d | sed 's|\.||' > $all_files
    4.47  		orphans="$(sort $all_files $packaged | uniq -u)"
    4.48 -		if [ -n "$orphans" ]; then
    4.49 -			echo -n '<section><h3>Unpackaged files:</h3><pre class="files">'
    4.50 +		if [ -d "$wok/$main/install" -a -n "$orphans" ]; then
    4.51 +			echo '<section><h3>Unpackaged files:</h3>'
    4.52 +			table=$(mktemp)
    4.53  			echo "$orphans" | awk '
    4.54  			function tag(text, color) { printf("<span class=\"c%s1\">%s</span> %s\n", color, text, $0); }
    4.55 -			/\/perllocal.pod$/ || /\/\.packlist$/ || /\/share\/bash-completion\// || /\/lib\/systemd\// { tag("---", 0); next }
    4.56 +			/\/perllocal.pod$/ || /\/\.packlist$/ || /\/share\/bash-completion\// ||
    4.57 +				/\/lib\/systemd\// || /\.pyc$/ || /\.pyo$/ { tag("---", 0); next }
    4.58  			/\.pod$/  { tag("pod", 5); next }
    4.59  			/\/share\/man\// { tag("man", 5); next }
    4.60 -			/\/share\/doc\// || /\/share\/gtk-doc\// || /\/share\/info\// || /\/share\/devhelp\// { tag("doc", 5); next }
    4.61 +			/\/share\/doc\// || /\/share\/gtk-doc\// || /\/share\/info\// ||
    4.62 +				/\/share\/devhelp\// { tag("doc", 5); next }
    4.63  			/\/share\/icons\// { tag("ico", 2); next }
    4.64  			/\/share\/locale\// { tag("loc", 4); next }
    4.65  			/\.h$/ || /\.a$/ || /\.la$/ || /\.pc$/ || /\/bin\/.*-config$/ { tag("dev", 3); next }
    4.66  			{ tag("???", 1) }
    4.67 -			'
    4.68 +			' > $table
    4.69 +
    4.70 +			# Summary table
    4.71 +			for i in head body; do
    4.72 +				case $i in
    4.73 +					head) echo -n '<table class="summary"><tr>';;
    4.74 +					body) echo -n '<th> </th></tr><tr>';;
    4.75 +				esac
    4.76 +				for j in '???1' dev3 loc4 ico2 doc5 man5 pod5 '---0'; do
    4.77 +					tag=${j:0:3}; class="c${j:3:1}0"; [ "$class" == 'c00' ] && class='c01'
    4.78 +					case $i in
    4.79 +						head) echo -n "<th class='$class'>$tag</th>";;
    4.80 +						body) printf '<td>%s</td>' "$(grep ">$tag<" $table | wc -l)";;
    4.81 +					esac
    4.82 +				done
    4.83 +			done
    4.84 +			echo '<td> </td></tr></table>'
    4.85 +
    4.86 +			echo -n '<pre class="files">'
    4.87 +			cat $table
    4.88  			echo '</pre></section>'
    4.89 +			rm $table
    4.90  		fi
    4.91 +		rm $packaged $all_files
    4.92  		;;
    4.93  
    4.94  	description)
    4.95 @@ -1243,15 +1275,24 @@
    4.96  
    4.97  					if [ -n "$(echo "$html" | fgrep 'The requested file /tmp/tmp.')" ]; then
    4.98  						# Process the pre-formatted man-cat page
    4.99 -						echo '<pre>'
   4.100 -						sed '
   4.101 +						# (for example see sudo package without groff in build dependencies)
   4.102 +						sed -i '
   4.103  							s|M-bM-^@M-^S|—|g;
   4.104  							s|M-bM-^@M-^\\|<b>|g;
   4.105  							s|M-bM-^@M-^]|</b>|g
   4.106  							s|M-bM-^@M-^X|<u>|g;
   4.107  							s|M-bM-^@M-^Y|</u>|g;
   4.108  							s|M-BM-||g;
   4.109 +							s|++oo|•|g;
   4.110 +							s|&|\&amp;|g; s|<|\&lt;|g; s|>|\&gt;|g;
   4.111  							' "$tmp"
   4.112 +						for i in a b c d e f g h i j k l m n o p q r s t u v w x y z \
   4.113 +								 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z \
   4.114 +								 0 1 2 3 4 5 6 7 8 9 _ - '\\+' '\.' /; do
   4.115 +							sed -i "s|$i$i|<b>$i</b>|g; s|_$i|<u>$i</u>|g" "$tmp"
   4.116 +						done
   4.117 +						echo '<pre class="catman">'
   4.118 +						sed 's|</b><b>||g; s|</u><u>||g; s|</u><b>_</b><u>|_|g; s|</b> <b>| |g;' "$tmp"
   4.119  						echo '</pre>'
   4.120  					else
   4.121  						echo "$html"
     5.1 --- a/modules/compressor	Thu Jun 01 19:27:13 2017 +0100
     5.2 +++ b/modules/compressor	Mon Jun 05 15:59:11 2017 +0300
     5.3 @@ -6,10 +6,6 @@
     5.4  
     5.5  . /usr/lib/slitaz/libcook.sh
     5.6  
     5.7 -# tazpkg install command
     5.8 -tpi='tazpkg -gi --quiet --local --cookmode'
     5.9 -
    5.10 -
    5.11  # Compressor cache stuff
    5.12  
    5.13  comp_cache_root='/home/slitaz/cache/cook'
    5.14 @@ -30,6 +26,13 @@
    5.15  #
    5.16  
    5.17  
    5.18 +# tazpkg install command
    5.19 +
    5.20 +tpi() {
    5.21 +	tazpkg -gi --quiet --local --cookmode $1
    5.22 +}
    5.23 +
    5.24 +
    5.25  # Working with time (with hundredths precision)
    5.26  
    5.27  get_time() {
    5.28 @@ -123,7 +126,7 @@
    5.29  	[ -d "$manpath" ] || return
    5.30  	size0=$(sizes man); [ -z "$size0" ] && return
    5.31  
    5.32 -	$tpi advancecomp
    5.33 +	tpi advancecomp
    5.34  
    5.35  	action 'Compressing man pages...'
    5.36  
    5.37 @@ -162,7 +165,7 @@
    5.38  	[ "${COOKOPTS/!gz/}" != "$COOKOPTS" ] && return
    5.39  	size0=$(sizes gz); [ -z "$size0" ] && return
    5.40  
    5.41 -	$tpi advancecomp
    5.42 +	tpi advancecomp
    5.43  
    5.44  	action 'Recompressing gzip files...'
    5.45  
    5.46 @@ -191,8 +194,8 @@
    5.47  	use_op=true
    5.48  	[ "${COOKOPTS/!pngquant/}" != "$COOKOPTS" ] && use_pq=false
    5.49  	[ "${COOKOPTS/!optipng/}"  != "$COOKOPTS" ] && use_op=false
    5.50 -	$use_pq && $tpi pngquant
    5.51 -	$use_op && $tpi optipng
    5.52 +	$use_pq && tpi pngquant
    5.53 +	$use_op && tpi optipng
    5.54  
    5.55  	action 'Compressing png images...'
    5.56  
    5.57 @@ -226,7 +229,7 @@
    5.58  	[ "${COOKOPTS/!svgz/}" != "$COOKOPTS" ] && return
    5.59  	size0=$(sizes svg); [ -z "$size0" ] && return
    5.60  
    5.61 -	$tpi svgcleaner
    5.62 +	tpi svgcleaner
    5.63  
    5.64  	action 'Compressing svg images...'
    5.65  
    5.66 @@ -257,7 +260,7 @@
    5.67  	[ "${COOKOPTS/!uiz/}" != "$COOKOPTS" ] && return
    5.68  	[ -z "$(find $install -type f \( -name '*.ui' -o -name '*.glade' \) )" ] && return
    5.69  
    5.70 -	$tpi xmlstarlet
    5.71 +	tpi xmlstarlet
    5.72  
    5.73  	action 'Compressing ui files...'
    5.74  
    5.75 @@ -312,7 +315,7 @@
    5.76  	time0=$(get_time)
    5.77  
    5.78  	if [ -n "$QA" -a -z "$(which desktop-file-validate)" ]; then
    5.79 -		$tpi desktop-file-utils-extra
    5.80 +		tpi desktop-file-utils-extra
    5.81  	fi
    5.82  
    5.83  	# The variable $LOCALE is set in cook.conf and may be overridden in the receipt.
    5.84 @@ -362,9 +365,9 @@
    5.85  	[ -z "$(find $install -type f -name '*.mo')" ] && return
    5.86  
    5.87  	# Gettext functions: msgunfmt, msguniq, msgconv, msgfmt
    5.88 -	$tpi gettext
    5.89 +	tpi gettext
    5.90  	# Gconv modules (convert to UTF-8)
    5.91 -	$tpi glibc-locale
    5.92 +	tpi glibc-locale
    5.93  
    5.94  	action 'Normalizing mo files...'
    5.95