cookutils rev 1010

Major release. cook: fix remove_already_packed(), now it works inside the set; package cooking stops if cookit() return non-zero return code while processing compile_rules() from receipt; lighttpd/index.cgi: 'files' page reworked, now it knows about the sets; finally fixed bug when out-of-tree files (such as pulled into $fs NOT from $install) mistakenly displayed as "unpackaged".
author Aleksej Bobylev <al.bobylev@gmail.com>
date Wed Nov 22 19:51:01 2017 +0200 (2017-11-22)
parents 845d62611d92
children 46fe75e9b709
files cook lighttpd/index.cgi
line diff
     1.1 --- a/cook	Sat Nov 18 16:38:50 2017 +0200
     1.2 +++ b/cook	Wed Nov 22 19:51:01 2017 +0200
     1.3 @@ -992,9 +992,8 @@
     1.4  	find . | cpio -o -H newc --quiet > ../$PACKAGE-$VERSION$EXTRAVERSION$arch.tazpkg
     1.5  	status
     1.6  
     1.7 -#	action 'Restoring original package tree...'
     1.8 +	# Restoring original package tree.
     1.9  	mv ../fs .
    1.10 -#	status
    1.11  
    1.12  	rm fs.cpio.lzma; cd ..
    1.13  
    1.14 @@ -1346,11 +1345,24 @@
    1.15  
    1.16  # Remove from current $fs files that are already packed (for receipts v2).
    1.17  # Note: the order in $SPLIT is very important.
    1.18 +# Note 2: working in the current set.
    1.19  
    1.20  remove_already_packed() {
    1.21  	local i j
    1.22 +	neighbors=$(
    1.23 +		echo $SPLIT" " \
    1.24 +		| awk -F$'\t' -vpkg="$PACKAGE" '
    1.25 +		BEGIN { RS = " "; FS = ":"; }
    1.26 +		      { set[$1] = $2; }
    1.27 +		END   {
    1.28 +		        current_set = set[pkg];
    1.29 +		        for (i in set)
    1.30 +		          { if (i != pkg && set[i] == current_set) print i; }
    1.31 +		}
    1.32 +	')
    1.33  	IFS=$'\n'
    1.34 -	for i in $taz/*/files.list; do
    1.35 +	for neighbor in $neighbors; do
    1.36 +		i="$taz/$neighbor-$VERSION$EXTRAVERSION/files.list"
    1.37  		[ -e "$i" ] || continue
    1.38  		while read j; do
    1.39  			[ -f $fs$j -o -h $fs$j ] || continue
    1.40 @@ -2030,10 +2042,24 @@
    1.41  		done
    1.42  
    1.43  		# Cook and pack or exit on error and log everything.
    1.44 -		cookit $@ 2>&1 | loglimit 50 > $LOGS/$pkg.log
    1.45 +		((((cookit $@ 2>&1; echo $? >&3) | loglimit 50 > $LOGS/$pkg.log) 3>&1) | (read rq; exit $rq))
    1.46 +		rq=$?	# the return code of `cookit $@` above command
    1.47 +
    1.48 +		# Remove build dependencies both when `cookit` done or fail
    1.49  		remove_deps | tee -a $LOGS/$pkg.log
    1.50  		cookit_quality
    1.51 +
    1.52 +		# Log and stop if `cookit` fails
    1.53 +		if [ $rq -eq 1 ]; then
    1.54 +			debug_info | tee -a $LOGS/$pkg.log
    1.55 +			put_status $pkg Failed
    1.56 +			rm -f $command
    1.57 +			broken; exit 1
    1.58 +		fi
    1.59 +
    1.60 +		# Proceed only if `cookit` return code is zero-OK
    1.61  		packall 2>&1 | loglimit 5 >> $LOGS/$pkg.log
    1.62 +
    1.63  		clean_log
    1.64  
    1.65  		# Exit if any error in packing.
     2.1 --- a/lighttpd/index.cgi	Sat Nov 18 16:38:50 2017 +0200
     2.2 +++ b/lighttpd/index.cgi	Wed Nov 22 19:51:01 2017 +0200
     2.3 @@ -574,7 +574,7 @@
     2.4  				 s|^\(-rwxr-xr-x\)|<span class='c21'>\1</span>|;
     2.5  				 s|^\(-rw-r--r--\)|<span class='c31'>\1</span>|;
     2.6  				 s|^\(drwxr-xr-x\)|<span class='c41'>\1</span>|;
     2.7 -				 s|^\([lrwxs-]*\)|<span class='c11'>\1</span>|;
     2.8 +				 s|^\([lrwxs-][lrwxs-]*\)|<span class='c11'>\1</span>|;
     2.9  				"
    2.10  			;;
    2.11  	esac
    2.12 @@ -1312,18 +1312,27 @@
    2.13  		page_header
    2.14  		pkg_info
    2.15  
    2.16 -		packaged=$(mktemp)
    2.17 -
    2.18  		# find main package
    2.19  		wanted=$(. $wok/$pkg/receipt; echo $WANTED)
    2.20  		main=${wanted:-$pkg}
    2.21 +		devpkg=''; [ -d "$wok/$main-dev" ] && devpkg="$main-dev"
    2.22  
    2.23 -		# identify split packages
    2.24 -		split="$main $(. $wok/$main/receipt; echo $SPLIT)"
    2.25 -		[ -d "$wok/$main-dev" ] && split="$split $main-dev"
    2.26 -		split="$(echo $split | tr ' ' '\n' | sort -u)"
    2.27 +		splitsets=$(echo $SPLIT" " \
    2.28 +			| awk '
    2.29 +				BEGIN { RS = " "; FS = ":"; }
    2.30 +				{ print $2; }' \
    2.31 +			| sort -u \
    2.32 +			| tr '\n' ' ' \
    2.33 +			| sed 's|^ *||; s| *$||')
    2.34  
    2.35 -		# finally we need the version
    2.36 +		splitpkgs=$(echo $SPLIT" " \
    2.37 +			| awk '
    2.38 +				BEGIN { RS = " "; FS = ":"; }
    2.39 +				{ print $1; }' \
    2.40 +			| tr '\n' ' ' \
    2.41 +			| sed 's|^ *||; s| *$||')
    2.42 +
    2.43 +		# we need the version
    2.44  		if [ -f "$WOK/linux/receipt" ]; then
    2.45  			kvers=$(. $WOK/linux/receipt; echo $VERSION)
    2.46  			kbasevers=$(echo $kvers | cut -d. -f1,2)
    2.47 @@ -1333,138 +1342,326 @@
    2.48  		fi
    2.49  		ver=$(. $wok/$main/receipt; echo $VERSION$EXTRAVERSION)
    2.50  
    2.51 +		echo "<section><h3>Quick jump:</h3>"
    2.52  
    2.53 -		echo "<section><h3>Quick jump:</h3><ul>"
    2.54 -		echo "$split" | sed 'p' | xargs printf "<li><a href='#%s'>%s</a></li>\n"
    2.55 -		echo "<li id='li-repeats' style='display:none'><a href='#repeats'>repeatedly packaged files</a></li>"
    2.56 -		echo "<li id='li-empty' style='display:none'><a href='#empty'>unpackaged empty folders</a></li>"
    2.57 -		echo "<li id='li-orphans' style='display:none'><a href='#orphans'>unpackaged files</a>"
    2.58 -		echo "<span id='orphansTypes'></span></li>"
    2.59 -		echo "</ul></section>"
    2.60  
    2.61 -		for p in $split; do
    2.62 -			namever="$p-$ver"
    2.63 -			if [ -d "$wok/$p/taz/$p-$ver" ]; then
    2.64 -				indir=$p
    2.65 -			elif [ -d "$wok/$main/taz/$p-$ver" ]; then
    2.66 -				indir=$main
    2.67 -			fi
    2.68 -			dir="$wok/$indir/taz/$p-$ver/fs"
    2.69 +		for part in head body; do
    2.70  
    2.71 -			size=$(du -hs $dir | awk '{ sub(/\.0/, ""); print $1 }')
    2.72 +			for set in '' $splitsets; do
    2.73 +				pkgsofset=$(echo $SPLIT" " \
    2.74 +					| awk -vset="$set" -vmain="$main" -vdev="$devpkg" '
    2.75 +						BEGIN {
    2.76 +							RS = " "; FS = ":";
    2.77 +							if (!set) print main;
    2.78 +							if (!set && dev) print dev;
    2.79 +						}
    2.80 +						{
    2.81 +							if ($2 == set) print $1;
    2.82 +						}' \
    2.83 +					| sort -u)
    2.84  
    2.85 -			echo "<section><h3 id='$p'>Contents of package “$namever” (${size:-empty}):</h3>"
    2.86 -			echo '<pre class="files">'
    2.87 -			if [ -s "$wok/$indir/taz/$p-$ver/files.list" ]; then
    2.88 -				echo -n '<span class="underline">permissions·lnk·user    ·'
    2.89 -				echo -en 'group   ·     size·date &amp; time ·name\n</span>'
    2.90 -				cd $dir
    2.91 -				find . -print0 | sort -z | xargs -0 ls -ldp --color=always | \
    2.92 -				syntax_highlighter files | \
    2.93 -				sed "s|\([^>]*\)>\.\([^<]*\)\(<.*\)$|\1 href='$base/$indir/browse/taz/$p-$ver/fs\2'>\2\3|;" | \
    2.94 -				awk 'BEGIN { FS="\""; }
    2.95 -					{ gsub("+", "%2B", $2); print; }'
    2.96 -			else
    2.97 -				echo 'No files'
    2.98 -			fi
    2.99 -			echo '</pre></section>'
   2.100 -			cat $wok/$indir/taz/$p-$ver/files.list >> $packaged
   2.101 -		done
   2.102 +				set_description=''
   2.103 +				[ -n "$splitsets" ] &&
   2.104 +				case "$set" in
   2.105 +					'')
   2.106 +						set_description=' (default set)'
   2.107 +						set_title='Default set'
   2.108 +						;;
   2.109 +					*)
   2.110 +						set_description=" (set “$set”)"
   2.111 +						set_title="Set “$set”"
   2.112 +						;;
   2.113 +				esac
   2.114  
   2.115 -		# find repeatedly packaged files
   2.116 -		repeats="$(sort $packaged | uniq -d)"
   2.117 -		if [ -n "$repeats" ]; then
   2.118 -			echo '<script>document.getElementById("li-repeats").style.display = "list-item"</script>'
   2.119 -			echo -n '<section><h3 id="repeats">Repeatedly packaged files:</h3><pre class="files">'
   2.120 -			echo "$repeats" | sed 's|^|<span class="c11">!!!</span> |'
   2.121 -			echo "</pre></section>"
   2.122 -		fi
   2.123 +				install="$wok/$main/install"
   2.124 +				[ -n "$set" ] && install="$install-$set"
   2.125  
   2.126 -		# find unpackaged empty folders
   2.127 -		emptydirs="$(
   2.128 -			cd $wok/$main/install
   2.129 -			find -type d | sed 's|\.||' | \
   2.130 -			while read d; do
   2.131 -				[ -z "$(ls "$wok/$main/install$d")" ] || continue
   2.132 -				echo $d
   2.133 -			done | \
   2.134 -			while read d; do
   2.135 -				notfound='yes'
   2.136 -				for p in $(cd $wok/$main/taz; ls); do
   2.137 -					if [ -d "$wok/$main/taz/$p/fs$d" ]; then
   2.138 -						notfound=''
   2.139 -						break
   2.140 -					fi
   2.141 -				done
   2.142 -				[ -n "$notfound" ] &&
   2.143 -				ls -ldp --color=always .$d | syntax_highlighter files | sed 's|>\./|>/|'
   2.144 -			done
   2.145 -		)"
   2.146 -		if [ -n "$emptydirs" ]; then
   2.147 -			echo '<script>document.getElementById("li-empty").style.display = "list-item"</script>'
   2.148 -			echo -n '<section><h3 id="empty">Unpackaged empty folders:</h3><pre class="files">'
   2.149 -			echo "$emptydirs"
   2.150 -			echo "</pre></section>"
   2.151 -		fi
   2.152 +				case $part in
   2.153 +					head)
   2.154 +						[ -n "$splitsets" ] &&
   2.155 +						case "$set" in
   2.156 +							'') echo "<ul><li>Default set:";;
   2.157 +							*)  echo "<li>Set “$set”:";;
   2.158 +						esac
   2.159 +						echo -e '\t<ul>'
   2.160 +						echo "$pkgsofset" | sed 'p' | xargs printf "\t\t<li><a href='#%s'>%s</a></li>\n"
   2.161 +						cat <<EOT
   2.162 +		<li id='li-repeats$set' style='display:none'>
   2.163 +			<a href='#repeats$set'>repeatedly packaged files</a></li>
   2.164 +		<li id='li-empty$set' style='display:none'>
   2.165 +			<a href='#empty$set'>unpackaged empty folders</a></li>
   2.166 +		<li id='li-outoftree$set' style='display:none'>
   2.167 +			<a href='#outoftree$set'>out-of-tree files</a></li>
   2.168 +		<li id='li-orphans$set' style='display:none'>
   2.169 +			<a href='#orphans$set'>unpackaged files</a>
   2.170 +			<span id='orphansTypes$set'></span></li>
   2.171 +EOT
   2.172 +						echo -e '\t</ul>'
   2.173 +						[ -n "$splitsets" ] && echo "</li>"
   2.174 +						;;
   2.175 +					body)
   2.176 +						all_files=$(mktemp)
   2.177 +						cd $install; find ! -type d | sed 's|\.||' > $all_files
   2.178  
   2.179 -		# find unpackaged files
   2.180 -		all_files=$(mktemp)
   2.181 -		cd $wok/$main/install; find ! -type d | sed 's|\.||' > $all_files
   2.182 -		orphans="$(sort $all_files $packaged | uniq -u)"
   2.183 -		if [ -d "$wok/$main/install" -a -n "$orphans" ]; then
   2.184 -			echo '<script>document.getElementById("li-orphans").style.display = "list-item"</script>'
   2.185 -			echo '<section><h3 id="orphans">Unpackaged files:</h3>'
   2.186 -			table=$(mktemp)
   2.187 -			echo "$orphans" | awk -vi="$base/$indir/browse/install" '
   2.188 -			function tag(text, color) {
   2.189 -				printf("<span class=\"c%s1\">%s</span> ", color, text);
   2.190 -				printf("<a class=\"c00\" href=\"%s\">%s</a>\n", i $0, $0);
   2.191 -			}
   2.192 -			/\/perllocal.pod$/ || /\/\.packlist$/ || /\/share\/bash-completion\// ||
   2.193 -				/\/lib\/systemd\// || /\.pyc$/ || /\.pyo$/ || /\/fonts\.scale$/ || /\/fonts\.dir$/ {
   2.194 -				tag("---", 0); next }
   2.195 -			/\.pod$/  { tag("pod", 5); next }
   2.196 -			/\/share\/man\// { tag("man", 5); next }
   2.197 -			/\/share\/doc\// || /\/share\/gtk-doc\// || /\/share\/info\// ||
   2.198 -				/\/share\/devhelp\// { tag("doc", 5); next }
   2.199 -			/\/share\/icons\// { tag("ico", 2); next }
   2.200 -			/\/share\/locale\// { tag("loc", 4); next }
   2.201 -			/\.h$/ || /\.a$/ || /\.la$/ || /\.pc$/ || /\/bin\/.*-config$/ ||
   2.202 -				/\/Makefile.*$/ { tag("dev", 3); next }
   2.203 -			/\/share\/help\// || /\/share\/appdata\// { tag("gnm", 6); next }
   2.204 -			{ tag("???", 1) }
   2.205 -			' > $table
   2.206 +						# ------------------------------------------------------
   2.207 +						# Packages content
   2.208 +						# ------------------------------------------------------
   2.209 +						packaged=$(mktemp)
   2.210 +						for p in $pkgsofset; do
   2.211 +							namever="$p-$ver"
   2.212 +							if [ -d "$wok/$p/taz/$p-$ver" ]; then
   2.213 +								indir=$p
   2.214 +							elif [ -d "$wok/$main/taz/$p-$ver" ]; then
   2.215 +								indir=$main
   2.216 +							fi
   2.217 +							dir="$wok/$indir/taz/$p-$ver/fs"
   2.218  
   2.219 -			# Summary table
   2.220 -			orphans_types='()'
   2.221 -			for i in head body; do
   2.222 -				case $i in
   2.223 -					head) echo -n '<table class="summary"><tr>';;
   2.224 -					body) echo -n '<th> </th></tr><tr>';;
   2.225 +							size=$(du -hs $dir | awk '{ sub(/\.0/, ""); print $1 }')
   2.226 +
   2.227 +							echo
   2.228 +							echo "<section id='$p'>"
   2.229 +							echo "	<h3>Contents of package “$namever” (${size:-empty}):</h3>"
   2.230 +							echo '	<pre class="files">'
   2.231 +							if [ -s "$wok/$indir/taz/$p-$ver/files.list" ]; then
   2.232 +								echo -en '<span class="underline">permissions·lnk·user    ·group   ·     size·date &amp; time ·name\n</span>'
   2.233 +								cd $dir
   2.234 +								find . -print0 \
   2.235 +								| sort -z \
   2.236 +								| xargs -0 ls -ldp --color=always \
   2.237 +								| syntax_highlighter files \
   2.238 +								| sed "s|\([^>]*\)>\.\([^<]*\)\(<.*\)$|\1 href='$base/$indir/browse/taz/$p-$ver/fs\2'>\2\3|;" \
   2.239 +								| awk 'BEGIN { FS="\""; }
   2.240 +									{ gsub("+", "%2B", $2); print; }'
   2.241 +							else
   2.242 +								echo 'No files'
   2.243 +							fi
   2.244 +							echo '</pre>'
   2.245 +							echo '</section>'
   2.246 +
   2.247 +							cat $wok/$indir/taz/$p-$ver/files.list >> $packaged
   2.248 +						done
   2.249 +						# ------------------------------------------------------
   2.250 +						# /Packages content
   2.251 +						# ------------------------------------------------------
   2.252 +
   2.253 +						# ------------------------------------------------------
   2.254 +						# Repeatedly packaged files
   2.255 +						# ------------------------------------------------------
   2.256 +						repeats=$(mktemp)
   2.257 +						sort $packaged | uniq -d > $repeats
   2.258 +						if [ -s "$repeats" ]; then
   2.259 +							echo
   2.260 +							echo "<script>document.getElementById('li-repeats$set').style.display = 'list-item'</script>"
   2.261 +							echo "<section id='repeats$set'>"
   2.262 +							echo "	<h3>Repeatedly packaged files$set_description:</h3>"
   2.263 +							cd $install
   2.264 +
   2.265 +							IFS=$'\n'
   2.266 +							echo -n '	<pre class="files">'
   2.267 +							echo -en '<span class="underline">permissions·lnk·user    ·group   ·     size·date &amp; time ·name\n</span>'
   2.268 +							while read i; do
   2.269 +								find .$i -exec ls -ldp --color=always '{}' \; \
   2.270 +								| syntax_highlighter files \
   2.271 +								| sed 's|>\./|>/|'
   2.272 +							done < $repeats
   2.273 +							echo '</pre>'
   2.274 +							echo '</section>'
   2.275 +							unset IFS
   2.276 +						fi
   2.277 +						rm $repeats
   2.278 +						# ------------------------------------------------------
   2.279 +						# /Repeatedly packaged files
   2.280 +						# ------------------------------------------------------
   2.281 +
   2.282 +						# ------------------------------------------------------
   2.283 +						# Unpackaged empty folders
   2.284 +						# ------------------------------------------------------
   2.285 +						emptydirs=$(mktemp)
   2.286 +						cd $install
   2.287 +						IFS=$'\n'
   2.288 +						find -type d \
   2.289 +						| sed 's|\.||' \
   2.290 +						| while read d; do
   2.291 +							[ -z "$(ls "$wok/$main/install$d")" ] || continue
   2.292 +							echo $d
   2.293 +						done \
   2.294 +						| while read d; do
   2.295 +							notfound='yes'
   2.296 +							for p in $(cd $wok/$main/taz; ls); do
   2.297 +								if [ -d "$wok/$main/taz/$p/fs$d" ]; then
   2.298 +									notfound=''
   2.299 +									break
   2.300 +								fi
   2.301 +							done
   2.302 +							[ -n "$notfound" ] &&
   2.303 +							ls -ldp --color=always .$d \
   2.304 +							| syntax_highlighter files \
   2.305 +							| sed 's|>\./|>/|'
   2.306 +						done > $emptydirs
   2.307 +						unset IFS
   2.308 +						if [ -s "$emptydirs" ]; then
   2.309 +							echo
   2.310 +							echo "<script>document.getElementById('li-empty$set').style.display = 'list-item'</script>"
   2.311 +							echo "<section id='empty$set'>"
   2.312 +							echo "	<h3>Unpackaged empty folders$set_description:</h3>"
   2.313 +							echo -n '	<pre class="files">'
   2.314 +							echo -en '<span class="underline">permissions·lnk·user    ·group   ·     size·date &amp; time ·name\n</span>'
   2.315 +							cat $emptydirs
   2.316 +							echo '</pre>'
   2.317 +							echo '</section>'
   2.318 +						fi
   2.319 +						rm $emptydirs
   2.320 +						# ------------------------------------------------------
   2.321 +						# /Unpackaged empty folders
   2.322 +						# ------------------------------------------------------
   2.323 +
   2.324 +						# ------------------------------------------------------
   2.325 +						# Out-of-tree files
   2.326 +						# ------------------------------------------------------
   2.327 +						outoftree=$(mktemp)
   2.328 +						awk -F$'\n' -vall="$all_files" '
   2.329 +							{
   2.330 +								if (FILENAME == all) files_all[$1] = "1";
   2.331 +								else                 files_pkg[$1] = "1";
   2.332 +							}
   2.333 +							END {
   2.334 +								for (i in files_pkg) {
   2.335 +									if (! files_all[i]) print i;
   2.336 +								}
   2.337 +							}
   2.338 +						' "$all_files" "$packaged" > $outoftree
   2.339 +
   2.340 +						if [ -d "$install" -a -s "$outoftree" ]; then
   2.341 +							echo
   2.342 +							echo "<script>document.getElementById('li-outoftree$set').style.display = 'list-item'</script>"
   2.343 +							echo "<section id='outoftree$set'>"
   2.344 +							echo "	<h3>Out-of-tree files$set_description:</h3>"
   2.345 +							echo -n '	<pre class="files">'
   2.346 +							echo -en '<span class="underline">permissions·lnk·user    ·group   ·     size·date &amp; time ·name\n</span>'
   2.347 +							IFS=$'\n'
   2.348 +							while read outoftree_line; do
   2.349 +								# Find the package out-of-tree file belongs to
   2.350 +								for i in $pkgsofset; do
   2.351 +									if grep -q "^$outoftree_line$" $wok/$main/taz/$i-$ver/files.list; then
   2.352 +										cd $wok/$main/taz/$i-$ver/fs
   2.353 +										ls -ldp --color=always ".$outoftree_line" \
   2.354 +										| syntax_highlighter files \
   2.355 +										| sed "s|\([^>]*\)>\.\([^<]*\)\(<.*\)$|\1 href='$base/$main/browse/taz/$i-$ver/fs\2'>\2\3|;" \
   2.356 +										| awk 'BEGIN { FS="\""; }
   2.357 +											{ gsub("+", "%2B", $2); print; }'
   2.358 +									fi
   2.359 +								done
   2.360 +							done < $outoftree
   2.361 +							unset IFS
   2.362 +							echo '</pre>'
   2.363 +							echo '</section>'
   2.364 +						fi
   2.365 +						rm $outoftree
   2.366 +						# ------------------------------------------------------
   2.367 +						# /Out-of-tree files
   2.368 +						# ------------------------------------------------------
   2.369 +
   2.370 +						# ------------------------------------------------------
   2.371 +						# Unpackaged files
   2.372 +						# ------------------------------------------------------
   2.373 +						orphans=$(mktemp)
   2.374 +						awk -vall="$all_files" '
   2.375 +							{
   2.376 +								if (FILENAME == all) files_all[$1] = "1";
   2.377 +								else                 files_pkg[$1] = "1";
   2.378 +							}
   2.379 +							END {
   2.380 +								for (i in files_all) {
   2.381 +									if (! files_pkg[i]) print i;
   2.382 +								}
   2.383 +							}
   2.384 +						' "$all_files" "$packaged" > $orphans
   2.385 +						if [ -d "$install" -a -s "$orphans" ]; then
   2.386 +							echo
   2.387 +							echo "<script>document.getElementById('li-orphans$set').style.display = 'list-item'</script>"
   2.388 +							echo "<section id='orphans$set'>"
   2.389 +							echo "	<h3>Unpackaged files$set_description:</h3>"
   2.390 +							table=$(mktemp)
   2.391 +							awk '
   2.392 +							function tag(text, color) {
   2.393 +								printf("<span class=\"c%s1\">%s</span> ", color, text);
   2.394 +								printf("%s\n", $0);
   2.395 +							}
   2.396 +							/\/perllocal.pod$/ || /\/\.packlist$/ || /\/share\/bash-completion\// ||
   2.397 +								/\/lib\/systemd\// || /\.pyc$/ || /\.pyo$/ || /\/fonts\.scale$/ || /\/fonts\.dir$/ {
   2.398 +								tag("---", 0); next }
   2.399 +							/\.pod$/  { tag("pod", 5); next }
   2.400 +							/\/share\/man\// { tag("man", 5); next }
   2.401 +							/\/share\/doc\// || /\/share\/gtk-doc\// || /\/share\/info\// ||
   2.402 +								/\/share\/devhelp\// { tag("doc", 5); next }
   2.403 +							/\/share\/icons\// { tag("ico", 2); next }
   2.404 +							/\/share\/locale\// { tag("loc", 4); next }
   2.405 +							/\.h$/ || /\.a$/ || /\.la$/ || /\.pc$/ || /\/bin\/.*-config$/ ||
   2.406 +								/\/Makefile.*$/ { tag("dev", 3); next }
   2.407 +							/\/share\/help\// || /\/share\/appdata\// { tag("gnm", 6); next }
   2.408 +							{ tag("???", 1) }
   2.409 +							' "$orphans" > $table
   2.410 +
   2.411 +							# Summary table
   2.412 +							orphans_types='()'
   2.413 +							for i in head body; do
   2.414 +								case $i in
   2.415 +									head) echo -n '<table class="summary"><tr>';;
   2.416 +									body) echo -n '<th> </th></tr><tr>';;
   2.417 +								esac
   2.418 +								for j in '???1' dev3 loc4 ico2 doc5 man5 pod5 gnm6 '---0'; do
   2.419 +									tag=${j:0:3}; class="c${j:3:1}0"; [ "$class" == 'c00' ] && class='c01'
   2.420 +									case $i in
   2.421 +										head) echo -n "<th class='$class'>$tag</th>";;
   2.422 +										body)
   2.423 +											tagscount="$(grep ">$tag<" $table | wc -l)"
   2.424 +											printf '<td>%s</td>' "$tagscount"
   2.425 +											[ "$tagscount" -gt 0 ] && orphans_types="${orphans_types/)/ $tag)}"
   2.426 +											;;
   2.427 +									esac
   2.428 +								done
   2.429 +							done
   2.430 +							echo '<td> </td></tr></table>'
   2.431 +							orphans_types="${orphans_types/( /(}"
   2.432 +							[ "$orphans_types" != '()' ] &&
   2.433 +							echo "<script>document.getElementById('orphansTypes$set').innerText = '${orphans_types// /, }';</script>"
   2.434 +
   2.435 +							i="$wok/$main/install$suffix"
   2.436 +							echo -n '	<pre class="files">'
   2.437 +							echo -en '<span class="underline">tag·permissions·lnk·user    ·group   ·     size·date &amp; time ·name\n</span>'
   2.438 +							IFS=$'\n'
   2.439 +							while read orphan_line; do
   2.440 +								echo -n "${orphan_line/span> */span>} "
   2.441 +								cd $i
   2.442 +								ls -ldp --color=always ".${orphan_line#*</span> }" \
   2.443 +								| syntax_highlighter files \
   2.444 +								| sed "s|\([^>]*\)>\.\([^<]*\)\(<.*\)$|\1 href='$base/$main/browse/install$suffix\2'>\2\3|;" \
   2.445 +								| awk 'BEGIN { FS="\""; }
   2.446 +									{ gsub("+", "%2B", $2); print; }'
   2.447 +							done < $table
   2.448 +							unset IFS
   2.449 +							echo '</pre>'
   2.450 +							echo '</section>'
   2.451 +							rm $table
   2.452 +						fi
   2.453 +						rm $orphans
   2.454 +						# ------------------------------------------------------
   2.455 +						# /Unpackaged files
   2.456 +						# ------------------------------------------------------
   2.457 +
   2.458 +						rm $all_files $packaged
   2.459 +						;;
   2.460  				esac
   2.461 -				for j in '???1' dev3 loc4 ico2 doc5 man5 pod5 gnm6 '---0'; do
   2.462 -					tag=${j:0:3}; class="c${j:3:1}0"; [ "$class" == 'c00' ] && class='c01'
   2.463 -					case $i in
   2.464 -						head) echo -n "<th class='$class'>$tag</th>";;
   2.465 -						body)
   2.466 -							tagscount="$(grep ">$tag<" $table | wc -l)"
   2.467 -							printf '<td>%s</td>' "$tagscount"
   2.468 -							[ "$tagscount" -gt 0 ] && orphans_types="${orphans_types/)/ $tag)}"
   2.469 -							;;
   2.470 -					esac
   2.471 -				done
   2.472 -			done
   2.473 -			echo '<td> </td></tr></table>'
   2.474 -			orphans_types="${orphans_types/( /(}"
   2.475 -			[ "$orphans_types" != '()' ] &&
   2.476 -				echo "<script>document.getElementById('orphansTypes').innerText = '${orphans_types// /, }';</script>"
   2.477 +			done # /set
   2.478  
   2.479 -			echo -n '<pre class="files">'
   2.480 -			cat $table
   2.481 -			echo '</pre></section>'
   2.482 -			rm $table
   2.483 -		fi
   2.484 -		rm $packaged $all_files
   2.485 +			case "$part" in
   2.486 +				head)
   2.487 +					[ -n "$splitsets" ] && echo "</ul>"
   2.488 +					echo "</section>"
   2.489 +					;;
   2.490 +			esac
   2.491 +		done # /part
   2.492 +
   2.493  		;;
   2.494  
   2.495  	description)