# HG changeset patch # User Aleksej Bobylev # Date 1484128384 -7200 # Node ID c6bbdbfdc2850d611f18a594fbef5e5c1e479f00 # Parent e6307b60adc813eb3b13d08a7d98e36ddfc524a6 Split modules/compressor (~500 lines of code) from cook. diff -r e6307b60adc8 -r c6bbdbfdc285 Makefile --- a/Makefile Wed Jan 11 00:31:18 2017 +0200 +++ b/Makefile Wed Jan 11 11:53:04 2017 +0200 @@ -28,7 +28,8 @@ install -m 0755 cooker $(DESTDIR)$(PREFIX)/bin install -m 0755 cookiso $(DESTDIR)$(PREFIX)/bin install -m 0755 cooklinux $(DESTDIR)$(PREFIX)/bin - install -m 0755 modules/pkgdb $(DESTDIR)$(PREFIX)/libexec/cookutils + install -m 0755 modules/pkgdb modules/compressor \ + $(DESTDIR)$(PREFIX)/libexec/cookutils install -m 0644 cook.conf $(DESTDIR)/etc/slitaz install -m 0644 cook.site $(DESTDIR)/etc/slitaz install -m 0644 web/* $(DESTDIR)/var/www/cgi-bin/cooker diff -r e6307b60adc8 -r c6bbdbfdc285 cook --- a/cook Wed Jan 11 00:31:18 2017 +0200 +++ b/cook Wed Jan 11 11:53:04 2017 +0200 @@ -480,311 +480,6 @@ } -# Get list of supported locales... - -get_supported_locales() { - local lpc='/slitaz-i18n/stuff/locale-pack.conf' LOCALE_PACK - if [ -e "$WOK$lpc" ]; then - # ... from package in the local wok - . "$WOK$lpc" - else - # ... from Hg - temp_conf=$(mktemp) - wget -q -O $temp_conf -T 10 "http://hg.slitaz.org/wok/raw-file/tip$lpc" - if [ -s $temp_conf ]; then - . $temp_conf - else - # Give up and use hardcoded list - LOCALE_PACK="ar ca cs da de el en es fi fr hr hu id is it ja nb nl nn pl pt \ - pt_BR ro ru sl sv tr uk zh_CN zh_TW" - fi - rm $temp_conf - fi - echo $LOCALE_PACK -} - - -# Fix common errors and warnings in the .desktop files -# Fixing can be disabled with COOKOPTS="!fixdesktops" - -fix_desktop_files() { - [ "${COOKOPTS/!fixdesktops/}" != "$COOKOPTS" ] && return - [ -z "$(find $install -type f -name '*.desktop')" ] && return - - local size0=$(find $install -type f -name '*.desktop' -exec ls -l \{\} \; | awk '{s+=$5}END{print s}') - local time0=$(date +%s) - - if [ -n "$QA" -a -z "$(which desktop-file-validate)" ]; then - tazpkg -gi desktop-file-utils-extra --quiet - fi - - # The variable $LOCALE is set in cook.conf and may be overridden in the receipt. - # Default value is "" (empty). That means for us that we'll use the full - # list of supported locales here. - [ -z "$LOCALE" ] && LOCALE=$(get_supported_locales) - - for desktop in $(find $install -type f -name '*.desktop'); do - cp "$desktop" "$desktop.orig" - - # Sort out .desktop file (is prerequisite to correct working of `fix-desktop-file`) - sdft "$desktop" -i - - # Fix common errors in .desktop file - fix-desktop-file "$desktop" - - # Strip unsupported locales from .desktop file - [ "${COOKOPTS/!i18nz/}" == "$COOKOPTS" ] && - sdft "$desktop" -i -k "$LOCALE" - - # Extra-strip - [ "${COOKOPTS/!extradesktops/}" == "$COOKOPTS" ] && - sdft "$desktop" -i -g -x -tf -r 'Keywords*' -o - - if [ -n "$QA" ]; then - # Check the rest of errors, warnings and tips - _ 'QA: Checking %s...' "$(basename $desktop)" - diff "$desktop.orig" "$desktop" - desktop-file-validate "$desktop" | busybox fold -s - echo - fi - - rm "$desktop.orig" - done - - local size1=$(find $install -type f -name '*.desktop' -exec ls -l \{\} \; | awk '{s+=$5}END{print s}') - local time1=$(date +%s) - comp_summary "$time0" "$time1" "$size0" "$size1" -} - - -# Compressor mini summary - -comp_summary() { - [ "$3" -eq 0 ] && return - local time=$(($2 - $1)) - local saving=$(( ($3 - $4) / 1024 )) - _ ' Time: %s. Size: %s B -> %s B. Save: %s KB' "$(disp_time $time)" "$3" "$4" "$saving" -} - - -# Find and strip: --strip-all (-s) or --strip-debug on static libs as well -# as removing unneeded files like in Python packages. Cross compiled binaries -# must be stripped with cross-tools aka $ARCH-slitaz-*-strip -# Stripping can be disabled with COOKOPTS="!strip" - -strip_package() { - [ "${COOKOPTS/!strip/}" != "$COOKOPTS" ] && return - - case "$ARCH" in - arm*|x86_64) export STRIP="$HOST_SYSTEM-strip" ;; - *) export STRIP='strip' ;; - esac - action 'Executing strip on all files...' - local size0=0 size1=0 oldsize newsize - local time0=$(date +%s) - - # Strip executable files - for dir in $fs/bin $fs/sbin $fs/usr/bin $fs/usr/sbin $fs/usr/games; do - if [ -d "$dir" ]; then - oldsize=$(find $dir -type f -exec ls -l '{}' \; | awk '{s+=$5}END{print s}') - find $dir -type f -exec $STRIP -s '{}' 2>/dev/null \; - newsize=$(find $dir -type f -exec ls -l '{}' \; | awk '{s+=$5}END{print s}') - size0=$((size0 + oldsize)); size1=$((size1 + newsize)) - fi - done - - # Strip shared and static libraries - # Remove Python *.pyc and *.pyo, Perl perllocal.pod and .packlist - oldsize=$(find $fs -type f \( \ - -name '*.so*' -o -name '*.a' -o \ - -name '*.pyc' -o -name '*.pyo' -o \ - -name 'perllocal.pod' -o -name '.packlist' \) -exec ls -l '{}' \; | awk '{s+=$5}END{print s}') - - find $fs -name '*.so*' -exec $STRIP -s '{}' 2>/dev/null \; - find $fs -name '*.a' -exec $STRIP --strip-debug '{}' 2>/dev/null \; - find $fs -type f \( -name '*.pyc' -o -name '*.pyo' \) -delete 2>/dev/null - find $fs -type f \( -name 'perllocal.pod' -o -name '.packlist' \) -delete 2>/dev/null - - newsize=$(find $fs -type f \( \ - -name '*.so*' -o -name '*.a' -o \) -exec ls -l '{}' \; | awk '{s+=$5}END{print s}') - - size0=$((size0 + oldsize)); size1=$((size1 + newsize)) - - local time1=$(date +%s) - status - comp_summary "$time0" "$time1" "$size0" "$size1" -} - - -# Strip unsupported locales (.mo files) - -strip_mo_i18n() { - [ "${COOKOPTS/!i18nz/}" != "$COOKOPTS" ] && return - - [ ! -d "$fs/usr/share/locale" ] && return - [ -z "$(find $fs/usr/share/locale -type f -name '*.mo')" ] && return - - action 'Thin out translation files...' - local size0=$(find $fs/usr/share/locale -type f -name '*.mo' -exec ls -l \{\} \; | awk '{s+=$5}END{print s}') - local time0=$(date +%s) - - # The variable $LOCALE is set in cook.conf and may be overridden in the receipt. - # Default value is "" (empty). That means for us that we'll use the full - # list of supported locales here. - [ -z "$LOCALE" ] && LOCALE=$(get_supported_locales) - - # Existing locales - elocales=" $(ls -1 "$fs/usr/share/locale" | tr '\n' ' ') " - - # Thin out the list of existing locales. At the end there will be only locales that need - # deleting (and the garbage like '_AU', _US', '_BR' leaving from 'en_AU', 'en_US', 'pt_BR'...) - for keep_locale in $LOCALE; do - elocales=${elocales//$keep_locale} - done - - # Remove the unsupported locales - for rem_locale in $elocales; do - [ -d "$fs/usr/share/locale/$rem_locale" ] && - rm -r "$fs/usr/share/locale/$rem_locale" - done - - local size1=$(find $fs -type f -name '*.mo' -exec ls -l \{\} \; | awk '{s+=$5}END{print s}') - local time1=$(date +%s) - status - comp_summary "$time0" "$time1" "$size0" "$size1" -} - - -# Normalize all *.mo files: unconditionally convert to UTF-8; remove strings that are not really added -# to the translation (msgid = msgstr) -# Normalization can be disabled with COOKOPTS="!monorm" - -normalize_mo() { - [ "${COOKOPTS/!monorm/}" != "$COOKOPTS" ] && return - [ -z "$(find $install -type f -name '*.mo')" ] && return - - action 'Normalizing mo files...' - local size0=$(find $install -type f -name '*.mo' -exec ls -l \{\} \; | awk '{s+=$5}END{print s}') - local time0=$(date +%s) - - # Gettext functions: msgunfmt, msguniq, msgconv, msgfmt - tazpkg -gi gettext --quiet - # Gconv modules (convert to UTF-8) - tazpkg -gi glibc-locale --quiet - - # Process all existing *.mo files - for mo in $(find "$install" -type f -name '*.mo'); do - tmpfile="$(mktemp)" - - msgunfmt "$mo" | msguniq | msgconv -o "$tmpfile" -t 'UTF-8' - # add newline - echo >> "$tmpfile" - - # get Plural-Forms - awk ' - BEGIN { skip = ""; } - { - if (! skip) { - s = $0; - gsub(/^[^\"]*\"/, "", s); - gsub(/\"$/, "", s); - printf("%s", s); - } - if (! $0) skip = "yes"; - } - ' "$tmpfile" | sed 's|\\n|\n|g' | grep "^Plural-Forms:" > "$tmpfile.pf" - - if ! grep -q 'msgid_plural' "$tmpfile"; then - echo > "$tmpfile.pf" - fi - - # main - awk -v pf="$(cat "$tmpfile.pf")" ' - function clean() { - mode = msgctxt = msgid = msgid_plural = msgstr = msgstr0 = msgstr1 = msgstr2 = msgstr3 = msgstr4 = msgstr5 = ""; - } - - function getstring() { - # Skip unquoted words at the beginning (msgid, msgstr...) and get string from inside quotes - s = $0; - gsub(/^[^\"]*\"/, "", s); - gsub(/\"$/, "", s); - return s; - } - - BEGIN { - printf("msgid \"\"\nmsgstr \"\"\n\"Content-Type: text/plain; charset=UTF-8\\n\"\n"); - if (pf) - printf("\"%s\\n\"\n", pf); - printf("\n"); - skip = 1; - clean(); - } - - { - # Skip the entire header - if (!skip) { - if ($1 == "msgctxt" || $1 == "msgid" || $1 == "msgstr" || $1 == "msgid_plural") - mode = $1; - if ($1 == "msgstr[0]") mode = "msgstr0"; - if ($1 == "msgstr[1]") mode = "msgstr1"; - if ($1 == "msgstr[2]") mode = "msgstr2"; - if ($1 == "msgstr[3]") mode = "msgstr3"; - if ($1 == "msgstr[4]") mode = "msgstr4"; - if ($1 == "msgstr[5]") mode = "msgstr5"; - - if (mode == "msgctxt") msgctxt = msgctxt getstring(); - if (mode == "msgid") msgid = msgid getstring(); - if (mode == "msgstr") msgstr = msgstr getstring(); - if (mode == "msgid_plural") msgid_plural = msgid_plural getstring(); - if (mode == "msgstr0") msgstr0 = msgstr0 getstring(); - if (mode == "msgstr1") msgstr1 = msgstr1 getstring(); - if (mode == "msgstr2") msgstr2 = msgstr2 getstring(); - if (mode == "msgstr3") msgstr3 = msgstr3 getstring(); - if (mode == "msgstr4") msgstr4 = msgstr4 getstring(); - if (mode == "msgstr5") msgstr5 = msgstr5 getstring(); - - if (! $0) { - if (msgid != msgstr) { - if (msgctxt) printf("msgctxt \"%s\"\n", msgctxt); - printf("msgid \"%s\"\n", msgid); - if (msgid_plural) printf("msgid_plural \"%s\"\n", msgid_plural); - if (msgstr) printf("msgstr \"%s\"\n", msgstr); - if (msgstr0) printf("msgstr[0] \"%s\"\n", msgstr0); - if (msgstr1) printf("msgstr[1] \"%s\"\n", msgstr1); - if (msgstr2) printf("msgstr[2] \"%s\"\n", msgstr2); - if (msgstr3) printf("msgstr[3] \"%s\"\n", msgstr3); - if (msgstr4) printf("msgstr[4] \"%s\"\n", msgstr4); - if (msgstr5) printf("msgstr[5] \"%s\"\n", msgstr5); - printf("\n"); - } - clean(); - } - } - if ($0 == "") skip = ""; - } - ' "$tmpfile" > "$tmpfile.awk" - - msgfmt "$tmpfile.awk" -o "$tmpfile.mo" - - if [ -s "$tmpfile.mo" ]; then - rm "$mo"; mv "$tmpfile.mo" "$mo" - else - _ 'Error processing %s' "$mo" - [ -e "$tmpfile.mo" ] && rm "$tmpfile.mo" - fi - - # Clean - rm "$tmpfile" "$tmpfile.pf" "$tmpfile.awk" - done - - local size1=$(find $install -type f -name '*.mo' -exec ls -l \{\} \; | awk '{s+=$5}END{print s}') - local time1=$(date +%s) - status - comp_summary "$time0" "$time1" "$size0" "$size1" -} - - # Remove files provided by split packages # For example: # 1. Package "pkg-main": @@ -841,147 +536,6 @@ } -# Function to compress all man pages -# Compressing can be disabled with COOKOPTS="!manz" - -compress_manpages() { - [ "${COOKOPTS/!manz/}" != "$COOKOPTS" ] && return - - case "$ARCH" in - arm*) return;; # While SliTaz-arm miss `advancecomp` - esac - local manpath="$install/usr/share/man" dest link - [ -d "$manpath" ] || return - - action 'Compressing man pages...' - - local size0=$(find $install/usr/share/man -type f -exec ls -l \{\} \; | awk '{s+=$5}END{print s}') - local time0=$(date +%s) - # We'll use only Gzip compression, so decompress other formats first - find $manpath -type f -name '*.bz2' -exec bunzip2 \{\} \; - find $manpath -type f -name '*.xz' -exec unxz \{\} \; - - # Fast compress with gzip - find $manpath -type f -name '*.[1-9]*' -exec gzip \{\} \; - - # Fix symlinks - for i in $(find $install/usr/share/man -type l); do - dest=$(readlink $i | sed 's|\.[gbx]z2*$||') - link=$(echo $i | sed 's|\.[gbx]z2*$||') - rm $i; ln -s $dest.gz $link.gz - done - - # Recompress with advdef (it can't compress, only recompress) - tazpkg -gi advancecomp --quiet - for i in $(find $install/usr/share/man -type f); do - advdef -z4q $i - done - - local size1=$(find $install/usr/share/man -type f -exec ls -l \{\} \; | awk '{s+=$5}END{print s}') - local time1=$(date +%s) - status - comp_summary "$time0" "$time1" "$size0" "$size1" -} - - -# Function used after compile_rules() to compress all png images -# Compressing can be disabled with COOKOPTS="!pngz" - -compress_png() { - [ "${COOKOPTS/!pngz/}" != "$COOKOPTS" ] && return - case "$ARCH" in - arm*) return;; # While SliTaz-arm miss `pngquant` and `optipng` - esac - [ -z "$(find $install -type f -name '*.png')" ] && return - - action 'Compressing png images...' - local size0=$(find $install -type f -name '*.png' -exec ls -l \{\} \; | awk '{s+=$5}END{print s}') - local time0=$(date +%s) - - local use_pq=true use_op=true - [ "${COOKOPTS/!pngquant/}" != "$COOKOPTS" ] && use_pq=false - [ "${COOKOPTS/!optipng/}" != "$COOKOPTS" ] && use_op=false - - $use_pq && tazpkg -gi pngquant --quiet - $use_op && tazpkg -gi optipng --quiet - - local oplevel=$(echo $COOKOPTS | grep 'op[0-8]' | sed 's|.*op\([0-8]\).*|\1|') - [ -z "$oplevel" ] && oplevel='2' - [ "$oplevel" == '8' ] && oplevel='7 -zm1-9' - - for i in $(find $install -type f -name '*.png'); do - $use_pq && pngquant -f --skip-if-larger --ext .png --speed 1 "$i" - $use_op && optipng -quiet -strip all -o$oplevel "$i" - done - - local size1=$(find $install -type f -name '*.png' -exec ls -l \{\} \; | awk '{s+=$5}END{print s}') - local time1=$(date +%s) - status - comp_summary "$time0" "$time1" "$size0" "$size1" -} - - -# Function used after compile_rules() to compress all svg images -# Compressing can be disabled with COOKOPTS="!svgz" - -compress_svg() { - [ "${COOKOPTS/!svgz/}" != "$COOKOPTS" ] && return - case "$ARCH" in - arm*) return;; # While SliTaz-arm miss `svgcleaner` - esac - [ -z "$(find $install -type f -name '*.svg')" ] && return - - action 'Compressing svg images...' - local size0=$(find $install -type f -name '*.svg' -exec ls -l \{\} \; | awk '{s+=$5}END{print s}') - local time0=$(date +%s) - tazpkg -gi svgcleaner --quiet - cleaner_log="$(mktemp)" - for i in $(find $install -type f -name '*.svg'); do - echo -n "$i: " >> "$cleaner_log" - svgcleaner "$i" "$i" --remove-unresolved-classes false --quiet true >> "$cleaner_log" - done - local size1=$(find $install -type f -name '*.svg' -exec ls -l \{\} \; | awk '{s+=$5}END{print s}') - local time1=$(date +%s) - status - comp_summary "$time0" "$time1" "$size0" "$size1" - sed -i '/: $/d' "$cleaner_log" - if [ -s "$cleaner_log" ]; then - _ 'Cleaner warnings and errors:' - awk '{printf " %s\n", $0;}' "$cleaner_log" - echo - fi - rm "$cleaner_log" -} - - -# Function used after compile_rules() to shrink all *.ui and *.glade files: -# remove insignificant spaces and comments -# Compressing can be disabled with COOKOPTS="!uiz" - -compress_ui() { - [ "${COOKOPTS/!uiz/}" != "$COOKOPTS" ] && return - case "$ARCH" in - arm*) return;; # While SliTaz-arm miss `xmlstarlet` - esac - [ -z "$(find $install -type f \( -name '*.ui' -o -name '*.glade' \) )" ] && return - - action 'Compressing ui files...' - local size0=$(find $install -type f \( -name '*.ui' -o -name '*.glade' \) -exec ls -l \{\} \; | awk '{s+=$5}END{print s}') - local time0=$(date +%s) - tazpkg -gi xmlstarlet --quiet - temp_ui="$(mktemp)" - for ui in $(find $install -type f \( -name '*.ui' -o -name '*.glade' \) ); do - xmlstarlet c14n --without-comments "$ui" | xmlstarlet sel -B -t -c '*' > "$temp_ui" - cat "$temp_ui" > "$ui" - done - local size1=$(find $install -type f \( -name '*.ui' -o -name '*.glade' \) -exec ls -l \{\} \; | awk '{s+=$5}END{print s}') - local time1=$(date +%s) - status - comp_summary "$time0" "$time1" "$size0" "$size1" - rm "$temp_ui" -} - - # The main cook function. cookit() { @@ -1199,12 +753,7 @@ # Skip all for split packages (already done in main package) if [ -z "$WANTED" ]; then footer - compress_manpages - compress_png - compress_svg - compress_ui - fix_desktop_files - normalize_mo + export COOKOPTS ARCH install; @@PREFIX@@/libexec/cookutils/compressor install fi footer @@ -1286,8 +835,7 @@ copy_generic_files # Strip and stuff files. - strip_package - strip_mo_i18n + export COOKOPTS ARCH HOST_SYSTEM LOCALE fs; @@PREFIX@@/libexec/cookutils/compressor fs # Create files.list with redirecting find output. action 'Creating the list of files...' diff -r e6307b60adc8 -r c6bbdbfdc285 modules/compressor --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/compressor Wed Jan 11 11:53:04 2017 +0200 @@ -0,0 +1,506 @@ +#!/bin/sh +# +# compressor - module of the SliTaz Cook +# Copyright (C) SliTaz GNU/Linux - GNU GPL v3 +# + +. /usr/lib/slitaz/libcook.sh + + +# +# Functions +# + + +# Display time. + +disp_time() { + div=$(( ($1 + 30) / 60)) + case $div in + 0) min='';; + # L10n: 'm' is for minutes (approximate time) + *) min=$(_n ' ~ %dm' "$div");; + esac + + # L10n: 's' is for seconds (cooking time) + _ '%ds%s' "$1" "$min" +} + + +# Compressor mini summary + +comp_summary() { + # "$time0" "$size0" "$size1" + time1=$(date +%s) + status + [ "$2" -eq 0 ] && return + time=$(($time1 - $1)) + saving=$(( ($2 - $3) / 1024 )) + _ ' Time: %s. Size: %s B -> %s B. Save: %s KB' "$(disp_time $time)" "$2" "$3" "$saving" +} + + +# Calculating different sizes + +sizes() { + case $1 in + man) find $install/usr/share/man -type f -exec ls -l \{\} \; ;; + png) find $install -type f -name '*.png' -exec ls -l \{\} \; ;; + svg) find $install -type f -name '*.svg' -exec ls -l \{\} \; ;; + xml) find $install -type f \( -name '*.ui' -o -name '*.glade' \) -exec ls -l \{\} \; ;; + des) find $install -type f -name '*.desktop' -exec ls -l \{\} \; ;; + mo1) find $install -type f -name '*.mo' -exec ls -l \{\} \; ;; + loc) find $install/usr/share/i18n/locales -type f -exec ls -l \{\} \; ;; + mo2) find $fs/usr/share/locale -type f -name '*.mo' -exec ls -l \{\} \; ;; + esac | awk '{s+=$5}END{print s}' +} + + +# Function to compress all man pages +# Compressing can be disabled with COOKOPTS="!manz" + +compress_manpages() { + time0=$(date +%s) + [ "${COOKOPTS/!manz/}" != "$COOKOPTS" ] && return + manpath="$install/usr/share/man" + [ -d "$manpath" ] || return + size0=$(sizes man); [ -z "$size0" ] && return + + action 'Compressing man pages...' + + # We'll use only Gzip compression, so decompress other formats first + find $manpath -type f -name '*.bz2' -exec bunzip2 \{\} \; + find $manpath -type f -name '*.xz' -exec unxz \{\} \; + + # Fast compress with gzip + find $manpath -type f -name '*.[1-9]*' -exec gzip \{\} \; + + # Fix symlinks + for i in $(find $install/usr/share/man -type l); do + dest=$(readlink $i | sed 's|\.[gbx]z2*$||') + link=$(echo $i | sed 's|\.[gbx]z2*$||') + rm $i; ln -s $dest.gz $link.gz + done + + # Recompress with advdef (it can't compress, only recompress) + tazpkg -gi advancecomp --quiet + for i in $(find $install/usr/share/man -type f); do + advdef -z4q $i + done + + comp_summary "$time0" "$size0" "$(sizes man)" +} + + +# Function used after compile_rules() to compress all png images +# Compressing can be disabled with COOKOPTS="!pngz" + +compress_png() { + time0=$(date +%s) + [ "${COOKOPTS/!pngz/}" != "$COOKOPTS" ] && return + size0=$(sizes png); [ -z "$size0" ] && return + + action 'Compressing png images...' + + use_pq=true + use_op=true + [ "${COOKOPTS/!pngquant/}" != "$COOKOPTS" ] && use_pq=false + [ "${COOKOPTS/!optipng/}" != "$COOKOPTS" ] && use_op=false + + $use_pq && tazpkg -gi pngquant --quiet + $use_op && tazpkg -gi optipng --quiet + + oplevel=$(echo $COOKOPTS | grep 'op[0-8]' | sed 's|.*op\([0-8]\).*|\1|') + [ -z "$oplevel" ] && oplevel='2' + [ "$oplevel" == '8' ] && oplevel='7 -zm1-9' + + for i in $(find $install -type f -name '*.png'); do + $use_pq && pngquant -f --skip-if-larger --ext .png --speed 1 "$i" + $use_op && optipng -quiet -strip all -o$oplevel "$i" + done + + comp_summary "$time0" "$size0" "$(sizes png)" +} + + +# Function used after compile_rules() to compress all svg images +# Compressing can be disabled with COOKOPTS="!svgz" + +compress_svg() { + time0=$(date +%s) + [ "${COOKOPTS/!svgz/}" != "$COOKOPTS" ] && return + size0=$(sizes svg); [ -z "$size0" ] && return + + action 'Compressing svg images...' + + tazpkg -gi svgcleaner --quiet + cleaner_log="$(mktemp)" + for i in $(find $install -type f -name '*.svg'); do + echo -n "$i: " >> "$cleaner_log" + svgcleaner "$i" "$i" --remove-unresolved-classes false --quiet true >> "$cleaner_log" + done + + comp_summary "$time0" "$size0" "$(sizes svg)" + + sed -i '/: $/d' "$cleaner_log" + if [ -s "$cleaner_log" ]; then + _ 'Cleaner warnings and errors:' + awk '{printf " %s\n", $0;}' "$cleaner_log" + echo + fi + rm "$cleaner_log" +} + + +# Function used after compile_rules() to shrink all *.ui and *.glade files: +# remove insignificant spaces and comments +# Compressing can be disabled with COOKOPTS="!uiz" + +compress_ui() { + [ "${COOKOPTS/!uiz/}" != "$COOKOPTS" ] && return + [ -z "$(find $install -type f \( -name '*.ui' -o -name '*.glade' \) )" ] && return + + action 'Compressing ui files...' + size0=$(sizes xml) + time0=$(date +%s) + tazpkg -gi xmlstarlet --quiet + temp_ui="$(mktemp)" + for ui in $(find $install -type f \( -name '*.ui' -o -name '*.glade' \) ); do + xmlstarlet c14n --without-comments "$ui" | xmlstarlet sel -B -t -c '*' > "$temp_ui" + cat "$temp_ui" > "$ui" + done + + comp_summary "$time0" "$size0" "$(sizes xml)" + rm "$temp_ui" +} + + +# Get list of supported locales... + +get_supported_locales() { + lpc='/slitaz-i18n/stuff/locale-pack.conf' + if [ -e "$WOK$lpc" ]; then + # ... from package in the local wok + . "$WOK$lpc" + else + # ... from Hg + temp_conf=$(mktemp) + wget -q -O $temp_conf -T 10 "http://hg.slitaz.org/wok/raw-file/tip$lpc" + if [ -s $temp_conf ]; then + . $temp_conf + else + # Give up and use hardcoded list + LOCALE_PACK="ar ca cs da de el en es fi fr hr hu id is it ja nb nl nn pl pt \ + pt_BR ro ru sl sv tr uk zh_CN zh_TW" + fi + rm $temp_conf + fi + echo $LOCALE_PACK +} + + +# Fix common errors and warnings in the .desktop files +# Fixing can be disabled with COOKOPTS="!fixdesktops" + +fix_desktop_files() { + [ "${COOKOPTS/!fixdesktops/}" != "$COOKOPTS" ] && return + [ -z "$(find $install -type f -name '*.desktop')" ] && return + + size0=$(sizes des) + time0=$(date +%s) + + if [ -n "$QA" -a -z "$(which desktop-file-validate)" ]; then + tazpkg -gi desktop-file-utils-extra --quiet + fi + + # The variable $LOCALE is set in cook.conf and may be overridden in the receipt. + # Default value is "" (empty). That means for us that we'll use the full + # list of supported locales here. + [ -z "$LOCALE" ] && LOCALE=$(get_supported_locales) + + for desktop in $(find $install -type f -name '*.desktop'); do + cp "$desktop" "$desktop.orig" + + # Sort out .desktop file (is prerequisite to correct working of `fix-desktop-file`) + sdft "$desktop" -i + + # Fix common errors in .desktop file + fix-desktop-file "$desktop" + + # Strip unsupported locales from .desktop file + [ "${COOKOPTS/!i18nz/}" == "$COOKOPTS" ] && + sdft "$desktop" -i -k "$LOCALE" + + # Extra-strip + [ "${COOKOPTS/!extradesktops/}" == "$COOKOPTS" ] && + sdft "$desktop" -i -g -x -tf -r 'Keywords*' -o + + if [ -n "$QA" ]; then + # Check the rest of errors, warnings and tips + _ 'QA: Checking %s...' "$(basename $desktop)" + diff "$desktop.orig" "$desktop" + desktop-file-validate "$desktop" | busybox fold -s + echo + fi + + rm "$desktop.orig" + done + + comp_summary "$time0" "$size0" "$(sizes des)" +} + + +# Normalize all *.mo files: unconditionally convert to UTF-8; remove strings that are not really added +# to the translation (msgid = msgstr) +# Normalization can be disabled with COOKOPTS="!monorm" + +normalize_mo() { + [ "${COOKOPTS/!monorm/}" != "$COOKOPTS" ] && return + [ -z "$(find $install -type f -name '*.mo')" ] && return + + action 'Normalizing mo files...' + size0=$(sizes mo1) + time0=$(date +%s) + + # Gettext functions: msgunfmt, msguniq, msgconv, msgfmt + tazpkg -gi gettext --quiet + # Gconv modules (convert to UTF-8) + tazpkg -gi glibc-locale --quiet + + # Process all existing *.mo files + for mo in $(find "$install" -type f -name '*.mo'); do + tmpfile="$(mktemp)" + + msgunfmt "$mo" | msguniq | msgconv -o "$tmpfile" -t 'UTF-8' + # add newline + echo >> "$tmpfile" + + # get Plural-Forms + awk ' + BEGIN { skip = ""; } + { + if (! skip) { + s = $0; + gsub(/^[^\"]*\"/, "", s); + gsub(/\"$/, "", s); + printf("%s", s); + } + if (! $0) skip = "yes"; + } + ' "$tmpfile" | sed 's|\\n|\n|g' | grep "^Plural-Forms:" > "$tmpfile.pf" + + if ! grep -q 'msgid_plural' "$tmpfile"; then + echo > "$tmpfile.pf" + fi + + # main + awk -v pf="$(cat "$tmpfile.pf")" ' + function clean() { + mode = msgctxt = msgid = msgid_plural = msgstr = msgstr0 = msgstr1 = msgstr2 = msgstr3 = msgstr4 = msgstr5 = ""; + } + + function getstring() { + # Skip unquoted words at the beginning (msgid, msgstr...) and get string from inside quotes + s = $0; + gsub(/^[^\"]*\"/, "", s); + gsub(/\"$/, "", s); + return s; + } + + BEGIN { + printf("msgid \"\"\nmsgstr \"\"\n\"Content-Type: text/plain; charset=UTF-8\\n\"\n"); + if (pf) + printf("\"%s\\n\"\n", pf); + printf("\n"); + skip = 1; + clean(); + } + + { + # Skip the entire header + if (!skip) { + if ($1 == "msgctxt" || $1 == "msgid" || $1 == "msgstr" || $1 == "msgid_plural") + mode = $1; + if ($1 == "msgstr[0]") mode = "msgstr0"; + if ($1 == "msgstr[1]") mode = "msgstr1"; + if ($1 == "msgstr[2]") mode = "msgstr2"; + if ($1 == "msgstr[3]") mode = "msgstr3"; + if ($1 == "msgstr[4]") mode = "msgstr4"; + if ($1 == "msgstr[5]") mode = "msgstr5"; + + if (mode == "msgctxt") msgctxt = msgctxt getstring(); + if (mode == "msgid") msgid = msgid getstring(); + if (mode == "msgstr") msgstr = msgstr getstring(); + if (mode == "msgid_plural") msgid_plural = msgid_plural getstring(); + if (mode == "msgstr0") msgstr0 = msgstr0 getstring(); + if (mode == "msgstr1") msgstr1 = msgstr1 getstring(); + if (mode == "msgstr2") msgstr2 = msgstr2 getstring(); + if (mode == "msgstr3") msgstr3 = msgstr3 getstring(); + if (mode == "msgstr4") msgstr4 = msgstr4 getstring(); + if (mode == "msgstr5") msgstr5 = msgstr5 getstring(); + + if (! $0) { + if (msgid != msgstr) { + if (msgctxt) printf("msgctxt \"%s\"\n", msgctxt); + printf("msgid \"%s\"\n", msgid); + if (msgid_plural) printf("msgid_plural \"%s\"\n", msgid_plural); + if (msgstr) printf("msgstr \"%s\"\n", msgstr); + if (msgstr0) printf("msgstr[0] \"%s\"\n", msgstr0); + if (msgstr1) printf("msgstr[1] \"%s\"\n", msgstr1); + if (msgstr2) printf("msgstr[2] \"%s\"\n", msgstr2); + if (msgstr3) printf("msgstr[3] \"%s\"\n", msgstr3); + if (msgstr4) printf("msgstr[4] \"%s\"\n", msgstr4); + if (msgstr5) printf("msgstr[5] \"%s\"\n", msgstr5); + printf("\n"); + } + clean(); + } + } + if ($0 == "") skip = ""; + } + ' "$tmpfile" > "$tmpfile.awk" + + msgfmt "$tmpfile.awk" -o "$tmpfile.mo" + + if [ -s "$tmpfile.mo" ]; then + rm "$mo"; mv "$tmpfile.mo" "$mo" + else + _ 'Error processing %s' "$mo" + [ -e "$tmpfile.mo" ] && rm "$tmpfile.mo" + fi + + # Clean + rm "$tmpfile" "$tmpfile.pf" "$tmpfile.awk" + done + + comp_summary "$time0" "$size0" "$(sizes mo1)" +} + + +# Strip locale definitions: normalize whitespace and remove comments +# Stripping can be disabled with COOKOPTS="!locdef" + +strip_locale_def() { + [ "${COOKOPTS/!locdef/}" != "$COOKOPTS" ] && return + [ ! -d "$install/usr/share/i18n/locales" ] && return + [ -z "$(find $install/usr/share/i18n/locales -type f)" ] && return + + action 'Stripping locale definitions...' + size0=$(sizes loc) + time0=$(date +%s) + + for i in $(find $install/usr/share/i18n/locales -type f); do + sed -i 's| | |g; s| *| |g; s|^ ||; /^%/d' $i + done + + comp_summary "$time0" "$size0" "$(sizes loc)" +} + + +# Find and strip: --strip-all (-s) or --strip-debug on static libs as well +# as removing unneeded files like in Python packages. Cross compiled binaries +# must be stripped with cross-tools aka $ARCH-slitaz-*-strip +# Stripping can be disabled with COOKOPTS="!strip" + +strip_package() { + [ "${COOKOPTS/!strip/}" != "$COOKOPTS" ] && return + + case "$ARCH" in + arm*|x86_64) export STRIP="$HOST_SYSTEM-strip" ;; + *) export STRIP='strip' ;; + esac + action 'Executing strip on all files...' + size0=0 + size1=0 + time0=$(date +%s) + + # Strip executable files + for dir in $fs/bin $fs/sbin $fs/usr/bin $fs/usr/sbin $fs/usr/games; do + if [ -d "$dir" ]; then + oldsize=$(find $dir -type f -exec ls -l '{}' \; | awk '{s+=$5}END{print s}') + find $dir -type f -exec $STRIP -s '{}' 2>/dev/null \; + newsize=$(find $dir -type f -exec ls -l '{}' \; | awk '{s+=$5}END{print s}') + size0=$((size0 + oldsize)); size1=$((size1 + newsize)) + fi + done + + # Strip shared and static libraries + # Remove Python *.pyc and *.pyo, Perl perllocal.pod and .packlist + oldsize=$(find $fs -type f \( \ + -name '*.so*' -o -name '*.a' -o \ + -name '*.pyc' -o -name '*.pyo' -o \ + -name 'perllocal.pod' -o -name '.packlist' \) -exec ls -l '{}' \; | awk '{s+=$5}END{print s}') + + find $fs -name '*.so*' -exec $STRIP -s '{}' 2>/dev/null \; + find $fs -name '*.a' -exec $STRIP --strip-debug '{}' 2>/dev/null \; + find $fs -type f \( -name '*.pyc' -o -name '*.pyo' \) -delete 2>/dev/null + find $fs -type f \( -name 'perllocal.pod' -o -name '.packlist' \) -delete 2>/dev/null + + newsize=$(find $fs -type f \( \ + -name '*.so*' -o -name '*.a' -o \) -exec ls -l '{}' \; | awk '{s+=$5}END{print s}') + + comp_summary "$time0" "$((size0 + oldsize))" "$((size1 + newsize))" +} + + +# Strip unsupported locales (.mo files) + +strip_mo_i18n() { + [ "${COOKOPTS/!i18nz/}" != "$COOKOPTS" ] && return + + [ ! -d "$fs/usr/share/locale" ] && return + [ -z "$(find $fs/usr/share/locale -type f -name '*.mo')" ] && return + + action 'Thin out translation files...' + size0=$(sizes mo2) + time0=$(date +%s) + + # The variable $LOCALE is set in cook.conf and may be overridden in the receipt. + # Default value is "" (empty). That means for us that we'll use the full + # list of supported locales here. + [ -z "$LOCALE" ] && LOCALE=$(get_supported_locales) + + # Existing locales + elocales=" $(ls -1 "$fs/usr/share/locale" | tr '\n' ' ') " + + # Thin out the list of existing locales. At the end there will be only locales that need + # deleting (and the garbage like '_AU', _US', '_BR' leaving from 'en_AU', 'en_US', 'pt_BR'...) + for keep_locale in $LOCALE; do + elocales=${elocales//$keep_locale} + done + + # Remove the unsupported locales + for rem_locale in $elocales; do + [ -d "$fs/usr/share/locale/$rem_locale" ] && + rm -r "$fs/usr/share/locale/$rem_locale" + done + + comp_summary "$time0" "$size0" "$(sizes mo2)" +} + + + + +case $1 in + install) + # Compressors working in the $install + case "$ARCH" in + arm*) ;; + *) + compress_manpages + compress_png + compress_svg + compress_ui + ;; + esac + + fix_desktop_files + normalize_mo + strip_locale_def + ;; + fs) + # Compressors working in the $fs + strip_package + strip_mo_i18n + ;; +esac diff -r e6307b60adc8 -r c6bbdbfdc285 modules/pkgdb --- a/modules/pkgdb Wed Jan 11 00:31:18 2017 +0200 +++ b/modules/pkgdb Wed Jan 11 11:53:04 2017 +0200 @@ -6,13 +6,6 @@ . /usr/lib/slitaz/libcook.sh -export output=raw - - -# Internationalization. - -export TEXTDOMAIN='cook' - # # Functions diff -r e6307b60adc8 -r c6bbdbfdc285 web/cooker.cgi --- a/web/cooker.cgi Wed Jan 11 00:31:18 2017 +0200 +++ b/web/cooker.cgi Wed Jan 11 11:53:04 2017 +0200 @@ -16,7 +16,7 @@ commits="$CACHE/commits" cooklist="$CACHE/cooklist" cookorder="$CACHE/cookorder" -command="$CACHE/command" +command="$CACHE/command"; touch $command blocked="$CACHE/blocked" broken="$CACHE/broken" cooknotes="$CACHE/cooknotes" @@ -315,7 +315,7 @@ bpkg=$pkg . $wok/$pkg/receipt - [ -n "$WANTED" ] && bpkg="$WANTED" + [ -n "$WANTED" ] && bpkg="${WANTED%% *}" # see locale-* with multiple WANTED [ -n "$WEB_SITE" ] && # busybox wget -s $WEB_SITE && echo "home"