#! /bin/sh # # Copyright (C) 2009-2010, 2014, 2018-2020 Free Software Foundation, Inc. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # Usage: convert-archive FROM TO [FROMFILE [TOFILE]] # where FROM is dir or dirgz or dirbz2 or dirxz or cvs or git # and TO is dir or dirgz or dirbz2 or dirxz or cvs or git # This will read FROMFILE (default: archive.$FROM.tar.gz) # and produce TOFILE (default: archive.$TO.tar.gz). progname=$0 package=@PACKAGE@ version=@VERSION@ # func_usage # outputs to stdout the --help usage message. func_usage () { echo "\ Usage: convert-archive FROM TO [FROMFILE [TOFILE]] Converts the archive of gettext infrastructure from the FROM format to the TO format. FROMFILE is the original file, defaulting to archive.\$FROM.tar.gz. TOFILE is the destination file, defaulting to archive.\$TO.tar.gz. Report bugs in the bug tracker at or by email to ." } # func_version # outputs to stdout the --version message. func_version () { echo "$progname (GNU $package) $version" echo "Copyright (C) 2009-2020 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law." echo "Written by" "Bruno Haible" } # func_fatal_error message # outputs to stderr a fatal error message, and terminates the program. func_fatal_error () { echo "convert-archive: *** $1" 1>&2 echo "convert-archive: *** Stop." 1>&2 exit 1 } # Command-line option processing. if { { test $# = 2 || test $# = 3 || test $# = 4; } \ && case "$1" in dir | cvs | git ) true;; *) false;; esac \ && case "$2" in dir | cvs | git ) true;; *) false;; esac; }; then : else echo "Usage: convert-archive {dir|cvs|git} {dir|cvs|git} [fromfile [tofile]]" exit 1 fi from="$1" to="$2" fromfile="$3" test -n "$fromfile" || fromfile=`pwd`/archive.$from.tar.gz tofile="$4" test -n "$tofile" || tofile=`pwd`/archive.$to.tar.gz unpacked=`pwd`/unpacked-files mkdir "$unpacked" || { if test -d "$unpacked"; then func_fatal_error "directory $unpacked already exists" else func_fatal_error "cannot create directory $unpacked" fi } # Unpack the original archive. case "$from" in dir*) { case "$from" in dir) cat < "$fromfile" ;; dirgz) gzip -d -c < "$fromfile" ;; dirbz2) bzip2 -d -c < "$fromfile" ;; dirxz) xz -d -c < "$fromfile" ;; esac } \ | (cd "$unpacked" && tar xf -) \ || func_fatal_error "file copy failed" ;; cvs) # Set variables # - work_dir directory containing the temporary checkout work_dir=tmpwrk$$ mkdir "$work_dir" || { if test -d "$work_dir"; then func_fatal_error "directory $work_dir already exists" else func_fatal_error "cannot create directory $work_dir" fi } # Set variables # - cvs_dir directory containing the temporary repository cvs_dir=tmpcvs$$ # Use an umask of 077, to avoid attacks that work by overwriting files in # the "$CVSROOT"/CVSROOT directory. (umask 077 && mkdir "$cvs_dir") || { if test -d "$cvs_dir"; then func_fatal_error "directory $cvs_dir already exists" else func_fatal_error "cannot create directory $cvs_dir" fi } CVSROOT=`pwd`/"$cvs_dir" unset CVS_CLIENT_LOG unset CVS_CLIENT_PORT unset CVS_IGNORE_REMOTE_ROOT unset CVS_LOCAL_BRANCH_NUM unset CVS_NOBASES unset CVS_PASSFILE unset CVS_PASSWORD unset CVS_PROXY_PORT unset CVS_RCMD_PORT unset CVS_RSH unset CVS_SERVER unset CVS_SERVER_SLEEP CVS_SIGN_COMMITS= export CVS_SIGN_COMMITS unset CVS_SSH unset CVS_VERIFY_CHECKOUTS unset CVS_VERIFY_TEMPLATE unset CVSIGNORE unset CVSREAD unset CVSREADONLYFS unset CVSUMASK unset CVSWRAPPERS # Need to pass -d "$CVSROOT", because there may be a CVS directory in the # current directory. cvs -d "$CVSROOT" init || func_fatal_error "cvs init failed" gzip -d -c < "$fromfile" | (cd "$cvs_dir" && tar xf -) # A witness that contains all versions. # Can be e.g. ABOUT-NLS, intl/ChangeLog, m4/gettext.m4. witness='ABOUT-NLS' # Get list of tags or versions. sed_extract_tags_from_log1='/^symbolic names:/{ :a /^ /p n ba } /^keyword substitution:/q' sed_extract_tags_from_log2='s/^ \([^:]*\):.*/\1/' rlog_harmless_warning_regex="warning: Unknown phrases like \`commitid \.\.\.;' are present\." tags=` ( LC_ALL=C rlog "$cvs_dir"/archive/$witness,v 2>&1 1>&3 \ | grep -v "$rlog_harmless_warning_regex" 1>&2 ) 3>&1 \ | sed -n -e "$sed_extract_tags_from_log1" \ | sed -e "$sed_extract_tags_from_log2"` test -n "$tags" || func_fatal_error "no release tags found" sed_tag_to_version='s/_/./g' for tag in $tags; do if test $tag != release; then version=`echo "$tag" | sed -e "$sed_tag_to_version"` (cd "$work_dir" cvs -d "$CVSROOT" checkout -r"$tag" archive > /dev/null 2> cvs.err \ || { cat cvs.err 1>&2; exit 1; } cat cvs.err | grep -v '^cvs checkout: Updating' find archive -name CVS -type d -print | xargs rm -rf rm -rf CVS ) || func_fatal_error "cvs checkout failed" mv "$work_dir"/archive "$unpacked/$version" fi done rm -rf "$cvs_dir" rm -rf "$work_dir" ;; git) # Set variables # - work_dir directory containing the temporary checkout work_dir=tmpwrk$$ mkdir "$work_dir" || { if test -d "$work_dir"; then func_fatal_error "directory $work_dir already exists" else func_fatal_error "cannot create directory $work_dir" fi } mkdir "$work_dir/master" || func_fatal_error "mkdir failed" gzip -d -c < "$fromfile" | (cd "$work_dir/master" && tar xf -) (unset GIT_CONFIG unset XDG_CONFIG_HOME unset HOME GIT_CONFIG_NOSYSTEM=1; export GIT_CONFIG_NOSYSTEM cd "$work_dir" tags=`cd master && git tag` test -n "$tags" || func_fatal_error "no release tags found" for tag in $tags; do if test $tag != empty; then version=$tag (cd master && git checkout -q $tag) \ || func_fatal_error "git checkout failed" rm -f master/.gitignore mv master/.git .git mkdir "$unpacked/$version" || func_fatal_error "mkdir failed" (cd master && tar cf - .) | (cd "$unpacked/$version" && tar xf -) \ || func_fatal_error "file copy failed" mv .git master/.git fi done ) rm -rf "$work_dir" ;; esac # Find a good 'tar' program. existing_file=gettext-0.10.35/ABOUT-NLS TAR=tar TAR_OPTIONS= for prog in tar gnutar gtar; do if (cd "$unpacked" && $prog cf - --owner=root --group=root "$existing_file") >/dev/null 2>&1; then TAR=$prog TAR_OPTIONS='--owner=root --group=root' break fi done # Create the target archive. case "$to" in dir*) (cd "$unpacked" && $TAR cf - $TAR_OPTIONS *) \ | { case "$to" in dir) cat > "$tofile" ;; dirgz) gzip -c -9 > "$tofile" ;; dirbz2) bzip2 -c -9 > "$tofile" ;; dirxz) xz -c -5 > "$tofile" ;; esac } \ || func_fatal_error "archive creation failed" ;; cvs) # Set variables # - cvs_dir directory containing the temporary repository cvs_dir=autopoint-files # Use an umask of 077, to avoid attacks that work by overwriting files in # the "$CVSROOT"/CVSROOT directory. (umask 077 && mkdir "$cvs_dir") || { if test -d "$cvs_dir"; then func_fatal_error "directory $cvs_dir already exists" else func_fatal_error "cannot create directory $cvs_dir" fi } CVSROOT=`pwd`/"$cvs_dir" unset CVS_CLIENT_LOG unset CVS_CLIENT_PORT unset CVS_IGNORE_REMOTE_ROOT unset CVS_PASSFILE unset CVS_PASSWORD unset CVS_RCMD_PORT unset CVS_RSH unset CVS_SERVER unset CVS_SERVER_SLEEP unset CVSIGNORE unset CVSREAD unset CVSUMASK unset CVSWRAPPERS # Set a nonstandard variable, for a good-looking cvs history. cvsuser=bruno gcc -shared -fPIC -O cvsuser.c -o cvsuser.so cvsuser_hack=`pwd`/cvsuser.so # Need to pass -d "$CVSROOT", because there may be a CVS directory in the # current directory. cvs -d "$CVSROOT" init || func_fatal_error "cvs init failed" # Add the contents of the unpacked directory to the repository. (cd "$unpacked" for version in *; do cvsver=`echo "$version" | sed -e 's/\./_/g'` (cd $version CVSUSER=$cvsuser LD_PRELOAD=$cvsuser_hack \ cvs -d "$CVSROOT" import -m "Import $version" archive release "$cvsver" > /dev/null ) || func_fatal_error "cvs import failed" # In order to avoid keyword substitution, we have to use "cvs admin" # in a temporary checkout. mkdir tmpcheckout || func_fatal_error "mkdir failed" (cd tmpcheckout \ && cvs -d "$CVSROOT" checkout -r"$cvsver" archive > /dev/null \ && cvs -d "$CVSROOT" admin -ko `find . -type f -print | sed -e 's,^\./,,' | grep -v '^CVS/' | grep -v '/CVS/'` > /dev/null ) 2> cvs.err || { cat cvs.err 1>&2; func_fatal_error "cvs checkout or admin failed"; } rm -rf tmpcheckout done ) (cd "$cvs_dir" && $TAR cf - $TAR_OPTIONS archive) \ | gzip -c -9 > "$tofile" \ || func_fatal_error "archive creation failed" rm -rf "$cvs_dir" cvsuser.so ;; git) git_dir=`pwd`/tmpgit$$ mkdir "$git_dir" || func_fatal_error "mkdir failed" unset GIT_CONFIG unset XDG_CONFIG_HOME unset HOME GIT_CONFIG_NOSYSTEM=1; export GIT_CONFIG_NOSYSTEM (cd "$git_dir" && { git init -q git config user.name 'GNU Gettext Build' git config user.email 'bug-gnu-gettext@gnu.org' touch .gitignore git add . git commit --author="Bruno Haible " \ --message="Empty directory" 2>&1 >/dev/null git tag empty }) || func_fatal_error "git init failed" sed_remove_leading_dot='s,^\./,,' sed_remove_git_infrastructure='/^\.git/d' (cd "$unpacked" for version in *; do (cd $version && tar cf - .) | \ (cd "$git_dir" && { prev_files=`find . -type f | sed -e "$sed_remove_leading_dot" -e "$sed_remove_git_infrastructure"` if test -n "$prev_files"; then git rm -q $prev_files fi tar xf - git add . git commit --author="Bruno Haible " \ --message="Import $version" 2>&1 >/dev/null git tag "$version" }) || func_fatal_error "file copy into git repository failed" done ) (cd "$git_dir" && git reset -q --hard empty && git repack -a -d -q) \ || func_fatal_error "git reset or repack failed" (cd "$git_dir" && $TAR cf - $TAR_OPTIONS .git) \ | gzip -c -9 > "$tofile" \ || func_fatal_error "archive creation failed" rm -rf "$git_dir" ;; esac rm -rf "$unpacked"