#!/bin/bash ######################################################################## # Copy a file system hierarchy to a destination tree, copying only # files that are either: language neutral, or specific to a particular # language. ######################################################################## # We assume the following naming convention, because that is what the # docs currently seem to use. # # -. is a language-specific file, such as # "foo-en.png". # # . is a language-neutral file, such as "foo.png". ######################################################################## # How Do We Choose Which Images Get Copied? # # We use two methods: one manual, the other automatic. If all your # image files conform to the above filename conventions, then we will # choose the appropriate image files automatically. If you name your # image files using another method, then you will need to list the # files to be copied in a "figs/Manifest-${LANG}" file. # # Before copying anything, we try to read the file "figs/Manifest-${LANG}" # for the list of files. If this file is missing, we will choose the # files based on the above naming convention. # # An easy way of generating the Manifest is like this: # # rm -f figs/Manifest-${LANG} # find figs -print >/tmp/Manifest-${LANG} && # mv /tmp/Manifest-${LANG} figs/ # # Then manually edit that file to remove anything you don't want copied. # Files matching "*/CVS/*" or "*/.svn/*" are ignored automatically. ######################################################################## targetLang=en bnFilter= DEBUG=no VERBOSE=no die() { printf "${ME}: %s\n" "$@" >&2 exit 1 } glob2sed() { s="" i=1 while true do c=$(echo "${1}" | cut -c$i) if [ -z "${c}" ]; then break fi case "${c}" in '.' ) s="${s}[.]" ;; '*' ) s="${s}.*" ;; '?' ) s="${s}." ;; * ) s="${s}${c}" ;; esac i=$(expr $i + 1) done echo "${s}" } ME=$(/bin/basename $0) USAGE="usage: ${ME} [-D] [-f glob] [-l lang] [-V] /path/to/source/dir /path/to/dest/dir" while getopts Df:l:v c do case "${c}" in D) DEBUG='';; f) sedFilter=$(glob2sed "${OPTARG}") bnFilter="${bnFilter} -e /^${sedFilter}$/p" ;; l) targetLang="${OPTARG}";; v) VERBOSE='';; *) echo "${USAGE}" >&2; exit 1;; esac done shift $(expr ${OPTIND} - 1) if [ $# -ne 2 ]; then echo "${USAGE}" >&2 exit 1 fi SRC="$1" DST="$2" shift 2 case "${SRC}" in /* ) ;; ~/* ) SRC=${HOME}/$(echo "${SRC}" | cut -c2,-) ;; * ) SRC="$(/bin/pwd)/${SRC}" ;; esac case "${DST}" in /* ) ;; ~/* ) DST=${HOME}/$(echo "${DST}" | cut -c2,-) ;; * ) DST="$(/bin/pwd)/${DST}" ;; esac if [ -z "${bnFilter}" ]; then bnFilter="-e /^.*$/p" fi [ "${DEBUG}" ] || echo >&2 "bnFilter=|${bnFilter}|" leadin=$(/usr/bin/dirname "${SRC}") [ "${DEBUG}" ] || echo >&2 "leadin=|${leadin}|" haveManifest=$( [ "${DEBUG}" ] || echo >&2 "Checking ${SRC}/Manifest-${targetLang}" if [ -f "${SRC}/Manifest-${targetLang}" ]; then echo yes else echo no fi ) [ "${DEBUG}" ] || echo >&2 "haveManifest=|${haveManifest}|" if [ "${haveManifest}" = "yes" ]; then [ "${VERBOSE}" ] || echo >&2 "Using manifest to get ${targetLang} file names" fi ( if [ "${haveManifest}" = "yes" ]; then # We have a manifest file, so get the list of # RELATIVE filenames from there. cat "${SRC}/Manifest-${targetLang}" else # No manifest, resort to a search find "${SRC}" -print fi ) | while read fn do [ "${DEBUG}" ] || echo >&2 "Considering '${fn}'" # Skip anything that even looks like CVS or SVN case "${fn}" in *CVS* | *.svn* ) continue ;; esac # Figure out the relative path for this pathname chunk if [ "${haveManifest}" = "yes" ]; then rp="${fn}" fn="${leadin}/${rp}" else rp=$( echo $(/usr/bin/dirname "${fn}")/$(/bin/basename "${fn}") | /bin/sed "s;^${leadin}/*;;" ) fi [ "${DEBUG}" ] || echo >&2 "rp=|${rp}|" # Copy directories, even if they are going to be empty. # Inodes are cheap, as long as you have enough. if [ -d "${fn}" ]; then [ "${VERBOSE}" ] || echo >&2 "Creating ${rp}" /bin/mkdir -p "${DST}"/"${rp}" continue fi # May not want this file under any circumstances bn=$(/bin/basename "${rp}") filteredBn=$(echo "${bn}" | sed -n ${bnFilter}) if [ "${haveManifest}" = "no" -a -z "${filteredBn}" ]; then [ "${DEBUG}" ] || echo >&2 "Filter rejects |${fn}|" continue fi # We want this file if the language matches or if it is # language neutral copyIt=${haveManifest} case "${bn}" in *-${targetLang}.* ) # Has matching language copyIt=yes ;; *-??.* | *-??_??.* ) # Doesn't match target language ;; * ) # Assume language neutral file copyIt=yes ;; esac [ "${DEBUG}" ] || echo >&2 "copyIt=${copyIt}" # Copy file if we like it if [ "${copyIt}" = "yes" ]; then [ "${VERBOSE}" ] || echo >&2 "Copying file |$fn|" /bin/mkdir -p $(/usr/bin/dirname "${DST}/${rp}") /bin/cp "${fn}" "${DST}/${rp}" else [ "${VERBOSE}" ] || echo >&2 "Rejecting file |$fn|" fi done