From: Mathieu Lutfy Date: Fri, 13 Mar 2015 01:51:34 +0000 (-0400) Subject: CRM-15832: Initial commit of tools/bin/scripts/create-pot-files.sh (moved from the... X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=7773dd1e500d94128e65ba1a81d740244caf56e5;p=civicrm-core.git CRM-15832: Initial commit of tools/bin/scripts/create-pot-files.sh (moved from the l10n repo). --- diff --git a/tools/bin/scripts/create-pot-files.sh b/tools/bin/scripts/create-pot-files.sh new file mode 100755 index 0000000000..e873318ada --- /dev/null +++ b/tools/bin/scripts/create-pot-files.sh @@ -0,0 +1,424 @@ +#!/bin/bash +set -e + +##################################################################### +## Variables + +## Source code path +SRC= + +## Output path +POTDIR= + +## The component *.pot files are based roughly on CRM/Foo templates/CRM/Foo. +COMPONENT_POTS="Admin Badge Batch Campaign Case Contribute Event Extension Financial Grant Mailing Member PCP Pledge Project Queue Report" + +## The adhoc *.pot files are based on clear file list (but may have some special/less predictable rules). +ADHOC_POTS="common-base countries drupal-civicrm install menu provinces" + +## The magic *.pot files are derived from other *.pot files. +MAGIC_POTS="common-components" + +## List of chosen *.pot files +POTS= + +## Header file to prepend to any *.pot +HEADER_TMPL=bin/header +HEADER= + +## Flags to control which actions are performed +DO_SCAN= +DO_DIGEST= +DO_CLEANUP= +FORCE= + +##################################################################### +function usage() { + cat < /dev/null ; then + echo "Missing required command: $cmd" + echo + case "$cmd" in + sponge) + echo 'This program uses the "sponge" command which you can get by installing the' + echo '"moreutils" package under Debian/Ubuntu or by visting' + echo 'https://joeyh.name/code/moreutils/' + ;; + civistrings) + echo 'This program uses the "civistrings" command which is bundled with buildkit.' + echo 'You can download it separately from https://github.com/civicrm/civistrings' + esac + exit 1 + fi + done +} + +##################################################################### +## civistrings wrapper with some default options +function _civistrings() { + civistrings --header="$HEADER" "$@" +} + +##################################################################### +## usage: HEADER=$(build_header "$HEADER_TMPL") +function build_header() { + local tmpl="$1" + local out="$POTDIR/.header" + local now=`date +'%F %R%z'` + + cat "$tmpl" \ + | sed "s/NOW/$now/" \ + > "$out" + + echo "$out" +} + +##################################################################### +## Build an individual POT file +## usage: build_raw_pot +## example: build_raw_pot Mailing +## example: build_raw_pot install +function build_raw_pot() { + local name="$1" + local filepath="$POTDIR/.raw-"$(echo $name | tr '[:upper:]' '[:lower:]').pot + + if [ -f "$filepath" -a -z "$FORCE" ]; then + echo "[[ Found raw strings for ${name} from previous scan. ]]" + return + fi + + echo "[[ Building raw strings for ${name} ]]" + + case "$name" in + + ## Adhoc targets, sorted alphabetically + + common-base) + _civistrings -o "$filepath" \ + {CRM,templates/CRM}/{ACL,Activity,Block,common,Contact,Core} \ + {CRM,templates/CRM}/{Custom,Dashlet,Dedupe,Export,Form,Friend} \ + {CRM,templates/CRM}/{Group,Import,Logging,Note,Price,Profile} \ + {CRM,templates/CRM}/{Relationship,SMS,Standalone,Tag,UF,Utils} \ + xml/templates/civicrm_acl.tpl \ + xml/templates/civicrm_data.tpl \ + xml/templates/languages.tpl \ + xml/templates/civicrm_msg_template.tpl \ + xml/templates/message_templates/friend_* \ + xml/templates/message_templates/uf_notify_* \ + packages/HTML/QuickForm \ + partials/ \ + js/ + + ## The CRM/Upgrade folder includes *.tpl files which, for some reason, + ## have been omitted from past pot's. Omitting these requires more + ## precise file selection. + find CRM/Upgrade -name '*.php' | _civistrings -ao "$filepath" - + _civistrings -ao "$filepath" templates/CRM/Upgrade + ;; + + common-components) + ## Not yet; handled in the digest phase. That why it's in MAGIC_POTS + return + ;; + + countries) + cat "$HEADER" > "$filepath" + grep ^INSERT xml/templates/civicrm_country.tpl \ + | cut -d\" -f4 \ + | while read entry; do + echo -e "msgctxt \"country\"\nmsgid \"$entry\"\nmsgstr \"\"\n" + done \ + >> "$filepath" + ## Hmm, if civicrm_country.tpl used {ts}, then we could just call "civistrings --msgctxt=country" + ;; + + drupal-civicrm) + _civistrings -o "$filepath" \ + drupal \ + CRM/Core/Permission.php + ;; + + install) + _civistrings -o "$filepath" \ + install/ + ;; + + menu) + cat "$HEADER" > "$filepath" + grep -h '' CRM/*/xml/Menu/*.xml \ + | sed 's/^.*<title>\(.*\)<\/title>.*$/\1/' \ + | while read entry; do + echo -e "msgctxt \"menu\"\nmsgid \"$entry\"\nmsgstr \"\"\n" + done \ + >> "$filepath" + _civistrings --msgctxt=menu xml/templates/civicrm_navigation.tpl -ao "$filepath" + ;; + + provinces) + cat "$HEADER" > "$filepath" + grep '^(' xml/templates/civicrm_state_province.tpl \ + | cut -d\" -f4 \ + | while read entry; do + echo -e "msgctxt \"province\"\nmsgid \"$entry\"\nmsgstr \"\"\n" + done \ + >> "$filepath" + ## Hmm, if civicrm_country.tpl used {ts}, then we could just call "civistrings --msgctxt=country" + ;; + + ## Standard targets, sorted alphabetically + + Campaign) + _civistrings -o "$filepath" \ + {CRM,templates/CRM}/$name \ + xml/templates/message_templates/petition_* + ;; + + Case) + _civistrings -o "$filepath" \ + {CRM,templates/CRM}/$name \ + xml/templates/message_templates/case_* + ;; + + Contribute) + _civistrings -o "$filepath" \ + {CRM,templates/CRM}/$name \ + xml/templates/message_templates/contribution_* \ + xml/templates/message_templates/test_* + ;; + + Event) + _civistrings -o "$filepath" \ + {CRM,templates/CRM}/$name \ + xml/templates/message_templates/event_* \ + xml/templates/message_templates/participant_* + ;; + + Member) + _civistrings -o "$filepath" \ + {CRM,templates/CRM}/$name \ + xml/templates/message_templates/membership_* + ;; + + PCP) + _civistrings -o "$filepath" \ + {CRM,templates/CRM}/$name \ + xml/templates/message_templates/pcp_* + ;; + + Pledge) + _civistrings -o "$filepath" \ + {CRM,templates/CRM}/$name \ + xml/templates/message_templates/pledge_* + ;; + + *) + if echo " $COMPONENT_POTS " | grep -q " $name " > /dev/null ; then + _civistrings -o "$filepath" {CRM,templates/CRM}/$name + else + echo "unrecognized pot: $name" + fi + ;; + + esac + + find "$filepath" ! -empty | while read f; do + msguniq "$filepath" | sponge "$filepath" + done +} + +##################################################################### +## usage: make_stat <name> +## example: make_stat Mailing +function make_stat() { + local name="$1" + local filepath="$POTDIR/.raw-"$(echo $name | tr '[:upper:]' '[:lower:]').pot + grep ^msgid "$filepath" | sort -u > "$filepath.msgid" + grep '^#:' "$filepath" | sed 's/#://' | tr ' ' '\n' | sort -u > "$filepath.files" +} + +##################################################################### +## Scan .raw-*.pot for common strings and put them in common-components.pot +## usage: build_common_components +function build_common_components() { + echo "[[ Building common-components.pot ]]" + local paths="" + local has_multiple=0 + for comp in $COMPONENT_POTS ; do + local rawfile=".raw-"$(echo $comp | tr '[:upper:]' '[:lower:]').pot + if [ -f "$rawfile" ]; then + paths="$paths $rawfile" + has_multiple=1 + fi + done + if [ $has_multiple -eq 1 ]; then + msgcomm $paths > .raw-common-components.pot + else + cat $HEADER > .raw-common-components.pot + fi +} + +##################################################################### +## example: build_final_pot Mailing +## example: build_final_pot install +function build_final_pot() { + local name="$1" + local rawpath="$POTDIR/.raw-"$(echo $name | tr '[:upper:]' '[:lower:]').pot + local finalpath="$POTDIR/"$(echo $name | tr '[:upper:]' '[:lower:]').pot + local tmpfile=`tempfile` + + echo "[[ Building final strings for ${name} ]]" + + cp -f "$rawpath" "$finalpath" + + if echo " $COMPONENT_POTS " | grep -q " $name " > /dev/null ; then + msgcomm "$finalpath" .raw-common-components.pot > $tmpfile + msgcomm --unique "$finalpath" $tmpfile | sponge "$finalpath" + + msgcomm "$finalpath" .raw-common-base.pot | sponge $tmpfile + msgcomm --unique "$finalpath" $tmpfile | sponge "$finalpath" + + elif [ "$name" == "install" ]; then + msgcomm "$finalpath" .raw-common-base.pot | sponge $tmpfile + msgcomm --unique "$finalpath" $tmpfile | sponge "$finalpath" + fi + + rm -f "$tmpfile" +} + +##################################################################### +## Delete temp files +function do_cleanup() { + echo "[[ Cleanup temp files ]]" + rm .header .raw*pot -f +} + +##################################################################### +## Main + +[ "$1" == "--help" ] && usage +[ "$1" == "-h" ] && usage + +check_deps + +FOUND_ACTION= +while getopts "asfdc" opt; do + case $opt in + a) + DO_SCAN=1 + DO_DIGEST=1 + DO_CLEANUP=1 + FOUND_ACTION=1 + ;; + s) + DO_SCAN=1 + FOUND_ACTION=1 + ;; + d) + DO_DIGEST=1 + FOUND_ACTION=1 + ;; + c) + DO_CLEANUP=1 + FOUND_ACTION=1 + ;; + f) + FORCE=1 + ;; + \?) + echo "Invalid option: -$OPTARG" >&2 + exit 1 + ;; + :) + echo "Option -$OPTARG requires an argument." >&2 + exit 1 + ;; + esac +done + +if [ -z "$FOUND_ACTION" ]; then + DO_SCAN=1 + DO_DIGEST=1 + DO_CLEANUP=1 +fi + +shift $((OPTIND-1)) + +[ "$1" == "" ] && echo 'source dir missing' && usage +test ! -e "$1" && echo 'source does not exist' && usage +test ! -d "$1" && echo 'source not a directory' && usage + +[ "$2" == "" ] && echo 'target dir missing' && usage +test ! -e "$2" && echo 'target does not exist' && usage +test ! -d "$2" && echo 'target not a directory' && usage + +# use absolute paths so that we can chdir/pushd +SRC=$(php -r 'echo realpath($argv[1]);' "$1") +POTDIR=$(php -r 'echo realpath($argv[1]);' "$2") +HEADER=$(build_header "$HEADER_TMPL") +## TODO: substitute "NOW" in HEADER +shift 2 + +if [ -z "$1" ]; then + POTS="$COMPONENT_POTS $ADHOC_POTS $MAGIC_POTS" +else + POTS="$@" +fi + +if [ -n "$DO_SCAN" ]; then + pushd "$SRC" >> /dev/null + for POT in $POTS ; do + build_raw_pot "$POT" + done + popd >> /dev/null +fi + +if [ -n "$DO_DIGEST" ]; then + pushd "$POTDIR" >> /dev/null + echo "POTS : $POTS" + build_common_components + for POT in $POTS ; do + echo "+++++++++ $POT" + build_final_pot "$POT" + done + popd >> /dev/null +fi + +if [ -n "$DO_CLEANUP" ]; then + pushd "$POTDIR" >> /dev/null + do_cleanup + popd >> /dev/null +fi