The Translation Project now provides rsync access, (just had to ask :-) thanks to Jeroen Dekkers for setting up rsyncd, and Benno Schulenberg for the quick replies. So along with some other changes, now coreutils' bootstrap script makes much more efficient use of network bandwidth. However, now it also retains a copy of each original .po file in e.g., po/.reference/. That is so that when you rerun bootstrap, it downloads only the usually-tiny differences, rather than whole files (though now they're rsync'd with -z).
Also, when only one .po file is modified, only one of your po/*.po files is updated. Before, they all would be updated, which would provoke a lot of wasted time running e.g., msgmerge. I deliberately chose to remove all wget support. If someone can make a really good case for reintroducing such support, even though now we can now use the far-superior rsync protocol, maybe someone will provide a patch. ------------------------------------ Import changes from coreutils for bootstrap script. * build-aux/bootstrap (WGET_COMMAND): Remove code to set this variable. bootstrap: uses rsync to download the .po files * build-aux/bootstrap (po_download_command_format): New global. (download_po_files): Use rsync. (update_po_files): Don't remove .po files after download, so future rsync runs can take advantage of the copies. * build-aux/bootstrap (gnulib_tool): Make sha1sum check quietly. Solve the unnecessary-.po-file-regeneration problem once and for all. * build-aux/bootstrap (download_po_files): New function, renamed from get_translations. Now, downloads, but doesn't update LINGUAS. (update_po_files): New function. bootstrap: Ignore more. * build-aux/bootstrap (symlink_to_dir): Add a directory name like uniwidth to e.g., lib/.gitignore. (slurp): Handle the sys_stat_.h -> sys mapping, too. * build-aux/bootstrap: New setting: vc_ignore. (insert_sorted_if_absent): Create $file if absent. Adapt to new, possibly empty, list: $vc_ignore. bootstrap: generate more ignorable names * build-aux/bootstrap (slurp): When generating ignorable names, also map .sin to .sed, .gperf to .c, and .y to .c. Index: build-aux/bootstrap =================================================================== RCS file: /cvsroot/gnulib/gnulib/build-aux/bootstrap,v retrieving revision 1.10 diff -u -p -r1.10 bootstrap --- build-aux/bootstrap 17 Aug 2007 23:13:57 -0000 1.10 +++ build-aux/bootstrap 2 Sep 2007 22:52:10 -0000 @@ -70,9 +70,13 @@ gnulib_modules= # Any gnulib files needed that are not in modules. gnulib_files= -# Translation Project URL, for the registry of all projects -# and for the translation-team master directory. -TP_URL="http://translationproject.org/latest/" +# The command to download all .po files for a specified domain into +# a specified directory. Fill in the first %s is the domain name, and +# the second with the destination directory. Use rsync's -L and -r +# options because the latest/%s directory and the .po files within are +# all symlinks. +po_download_command_format=\ +"rsync -Lrtvz 'translationproject.org::tp/latest/%s/' '%s'" extract_package_name=' /^AC_INIT(/{ @@ -129,9 +133,21 @@ checkout_only_file=README-hacking # Whether to use copies instead of symlinks. copy=false +# Set this to '.cvsignore .gitignore' in bootstrap.conf if you want +# those files to be generated in directories like lib/, m4/, and po/. +# Or set it to 'auto' to make this script select which to use based +# on which version control system (if any) is used in the source directory. +vc_ignore=auto + # Override the default configuration, if necessary. test -r bootstrap.conf && . ./bootstrap.conf +if test "$vc_ignore" = auto; then + vc_ignore= + test -d .git && vc_ignore=.gitignore + test -d CVS && vc_ignore="$vc_ignore .cvsignore" +fi + # Translate configuration into internal form. # Parse options. @@ -168,6 +184,7 @@ fi insert_sorted_if_absent() { file=$1 str=$2 + test -f $file || touch $file echo "$str" | sort -u - $file | cmp -s - $file \ || echo "$str" | sort -u - $file -o $file \ || exit 1 @@ -189,8 +206,9 @@ fi # below will malfunction. If creating it, also mark it as ignored. if test ! -d $build_aux; then mkdir $build_aux - for ig in .cvsignore .gitignore; do - test -f $ig && insert_sorted_if_absent $ig $build_aux + for dot_ig in x $vc_ignore; do + test $dot_ig = x && continue + insert_sorted_if_absent $dot_ig $build_aux done fi @@ -238,43 +256,49 @@ gnulib_tool=$GNULIB_SRCDIR/gnulib-tool # Get translations. -get_translations() { +download_po_files() { subdir=$1 domain=$2 + echo "$0: getting translations into $subdir for $domain..." + cmd=`printf "$po_download_command_format" "$domain" "$subdir"` + eval "$cmd" +} + +# Download .po files to $po_dir/.reference and copy only the new +# or modified ones into $po_dir. Also update $po_dir/LINGUAS. +update_po_files() { + # Directory containing primary .po files. + # Overwrite them only when we're sure a .po file is new. + po_dir=$1 + domain=$2 - case $WGET_COMMAND in - '') - echo "$0: wget not available; skipping translations";; - ?*) - echo "$0: getting translations into $subdir for $domain..." && - - (cd $subdir && rm -f dummy `ls | sed -n '/\.gmo$/p; /\.po/p'` && - $WGET_COMMAND -r -l1 -nd -np -A.po $TP_URL/$domain) - ;; - esac && - ls "$subdir"/*.po 2>/dev/null | - sed 's|.*/||; s|\.po$||' >"$subdir/LINGUAS" + # Download *.po files into this dir. + # Usually contains *.s1 checksum files. + ref_po_dir="$po_dir/.reference" + + test -d $ref_po_dir || mkdir $ref_po_dir || return + download_po_files $ref_po_dir $domain \ + && ls "$ref_po_dir"/*.po 2>/dev/null | + sed 's|.*/||; s|\.po$||' > "$po_dir/LINGUAS" + + for po in `cd $ref_po_dir && echo *.po|sed 's/\.po//g'`; do + new_po="$ref_po_dir/$po.po" + cksum_file="$ref_po_dir/$po.s1" + if ! sha1sum -c --status "$cksum_file" < "$new_po" > /dev/null; then + echo "updated $po_dir/$po.po..." + cp "$new_po" "$po_dir/$po.po" && sha1sum < "$new_po" > "$cksum_file" + fi + done } case $SKIP_PO in '') - case `wget --help` in - *'--no-cache'*) - WGET_COMMAND='wget -nv --no-cache';; - *'--cache=on/off'*) - WGET_COMMAND='wget -nv --cache=off';; - *'--non-verbose'*) - WGET_COMMAND='wget -nv';; - *) - WGET_COMMAND='';; - esac - if test -d po; then - get_translations po $package || exit + update_po_files po $package || exit fi if test -d runtime-po; then - get_translations runtime-po $package-runtime || exit + update_po_files runtime-po $package-runtime || exit fi;; esac @@ -288,7 +312,19 @@ symlink_to_dir() # If the destination directory doesn't exist, create it. # This is required at least for "lib/uniwidth/cjk.h". dst_dir=`dirname "$dst"` - test -d "$dst_dir" || mkdir -p "$dst_dir" + if ! test -d "$dst_dir"; then + mkdir -p "$dst_dir" + + # If we've just created a directory like lib/uniwidth, + # tell version control system(s) it's ignorable. + # FIXME: for now, this does only one level + parent=`dirname "$dst_dir"` + for dot_ig in x $vc_ignore; do + test $dot_ig = x && continue + ig=$parent/$dot_ig + insert_sorted_if_absent $ig `echo "$dst_dir"|sed 's,.*/,,'` + done + fi if $copy; then { @@ -428,14 +464,21 @@ slurp() { fi || exit done - for dot_ig in .cvsignore .gitignore; do + for dot_ig in x $vc_ignore; do + test $dot_ig = x && continue ig=$dir/$dot_ig - if test -n "$copied" && test -f $ig; then + if test -n "$copied"; then insert_sorted_if_absent $ig "$copied" # If an ignored file name ends with _.h, then also add # the name with just ".h". Many gnulib headers are generated, # e.g., stdint_.h -> stdint.h, dirent_.h ->..., etc. - f=`echo "$copied"|sed 's/_\.h$/.h/'` + # Likewise for .gperf -> .h, .y -> .c, and .sin -> .sed + f=`echo "$copied"|sed 's/_\.h$/.h/;s/\.sin$/.sed/;s/\.y$/.c/;s/\.gperf$/.h/'` + insert_sorted_if_absent $ig "$f" + + # For files like sys_stat_.h and sys_time_.h, record as + # ignorable the directory we might eventually create: sys/. + f=`echo "$copied"|sed 's/sys_.*_\.h$/sys/'` insert_sorted_if_absent $ig "$f" fi done