4 #####################################################################
13 ## The component *.pot files are based roughly on CRM/Foo templates/CRM/Foo.
14 COMPONENT_POTS
="Admin Badge Batch Campaign Case Contribute Event Extension Financial Grant Mailing Member PCP Pledge Project Queue Report"
16 ## The adhoc *.pot files are based on clear file list (but may have some special/less predictable rules).
17 ADHOC_POTS
="common-base countries drupal-civicrm install menu provinces"
19 ## The magic *.pot files are derived from other *.pot files.
20 MAGIC_POTS
="common-components"
22 ## List of chosen *.pot files
25 ## Header file to prepend to any *.pot
26 HEADER_TMPL
=bin
/header
29 ## Flags to control which actions are performed
35 #####################################################################
38 create-pot-files.sh - builds .pot files for CiviCRM.
41 ./bin/create-pot-files.sh [options] [srcdir] [destdir] [pot1...]
44 ./bin/create-pot-files.sh ~/repository/civicrm/ ~/repository/l10n/po/pot/
45 ./bin/create-pot-files.sh -sd ~/repository/civicrm/ ~/repository/l10n/po/pot/ common-base Admin Contribute
48 -s Scan targets for strings (Pass #1)
49 -d Digest/dedupe scanned strings (Pass #2)
51 -a All (scan+digest+cleanup; default)
52 -f Force (Ignore cached results from previous scan)
57 $ADHOC_POTS $MAGIC_POTS
59 Although you should probably not call this directly. Use build-unified-pots.sh
60 if you are exporting the strings to Transifex.
61 http://wiki.civicrm.org/confluence/display/CRMDOC/Pushing+new+strings+to+Transifex
68 #####################################################################
69 ## Assert that CLI dependencies are met
70 function check_deps
() {
71 for cmd
in sponge civistrings msgcomm msguniq tempfile
tr grep cut
date sed ; do
72 if ! which $cmd > /dev
/null
; then
73 echo "Missing required command: $cmd"
77 echo 'This program uses the "sponge" command which you can get by installing the'
78 echo '"moreutils" package under Debian/Ubuntu or by visting'
79 echo 'https://joeyh.name/code/moreutils/'
82 echo 'This program uses the "civistrings" command which is bundled with buildkit.'
83 echo 'You can download it separately from https://github.com/civicrm/civistrings'
90 #####################################################################
91 ## civistrings wrapper with some default options
92 function _civistrings
() {
93 civistrings
--header="$HEADER" "$@"
96 #####################################################################
97 ## usage: HEADER=$(build_header "$HEADER_TMPL")
98 function build_header
() {
100 local out
="$POTDIR/.header"
101 local now
=`date +'%F %R%z'`
104 |
sed "s/NOW/$now/" \
110 #####################################################################
111 ## Build an individual POT file
112 ## usage: build_raw_pot <name>
113 ## example: build_raw_pot Mailing
114 ## example: build_raw_pot install
115 function build_raw_pot
() {
117 local filepath
="$POTDIR/.raw-"$
(echo $name |
tr '[:upper:]' '[:lower:]').pot
119 if [ -f "$filepath" -a -z "$FORCE" ]; then
120 echo "[[ Found raw strings for ${name} from previous scan. ]]"
124 echo "[[ Building raw strings for ${name} ]]"
128 ## Adhoc targets, sorted alphabetically
131 _civistrings
-o "$filepath" \
132 {CRM
,templates
/CRM
}/{ACL
,Activity
,Block
,common
,Contact
,Core
} \
133 {CRM
,templates
/CRM
}/{Custom
,Dashlet
,Dedupe
,Export
,Form
,Friend
} \
134 {CRM
,templates
/CRM
}/{Group
,Import
,Logging
,Note
,Price
,Profile
} \
135 {CRM
,templates
/CRM
}/{Relationship
,SMS
,Standalone
,Tag
,UF
,Utils
} \
136 xml
/templates
/civicrm_acl.tpl \
137 xml
/templates
/civicrm_data.tpl \
138 xml
/templates
/languages.tpl \
139 xml
/templates
/civicrm_msg_template.tpl \
140 xml
/templates
/message_templates
/friend_
* \
141 xml
/templates
/message_templates
/uf_notify_
* \
142 ang
/crm
{App
,Attachment
,Example
,Ui
,Util
}{,.js
} \
146 js
/jquery
/jquery.crmeditable.js \
147 js
/jquery
/jquery.crmProfileSelector.js \
148 js
/jquery
/jquery.crmRevisionLink.js \
149 js
/jquery
/jquery.dashboard.js \
150 js
/model
/crm.designer.js \
152 js
/view
/crm.designer.js \
153 packages
/HTML
/QuickForm
155 ## The CRM/Upgrade folder includes *.tpl files which, for some reason,
156 ## have been omitted from past pot's. Omitting these requires more
157 ## precise file selection.
158 find CRM
/Upgrade
-name '*.php' | _civistrings
-ao "$filepath" -
159 _civistrings
-ao "$filepath" templates
/CRM
/Upgrade
163 ## Not yet; handled in the digest phase. That why it's in MAGIC_POTS
168 cat "$HEADER" > "$filepath"
169 grep ^INSERT xml
/templates
/civicrm_country.tpl \
171 |
while read entry
; do
172 echo -e "msgctxt \"country\"\nmsgid \"$entry\"\nmsgstr \"\"\n"
175 ## Hmm, if civicrm_country.tpl used {ts}, then we could just call "civistrings --msgctxt=country"
179 _civistrings
-o "$filepath" \
181 CRM
/Core
/Permission.php
185 _civistrings
-o "$filepath" \
190 cat "$HEADER" > "$filepath"
191 grep -h '<title>' CRM
/*/xml
/Menu
/*.xml \
192 |
sed 's/^.*<title>\(.*\)<\/title>.*$/\1/' \
193 |
while read entry
; do
194 echo -e "msgctxt \"menu\"\nmsgid \"$entry\"\nmsgstr \"\"\n"
197 _civistrings
--msgctxt=menu xml
/templates
/civicrm_navigation.tpl
-ao "$filepath"
201 cat "$HEADER" > "$filepath"
202 grep '^(' xml
/templates
/civicrm_state_province.tpl \
204 |
while read entry
; do
205 echo -e "msgctxt \"province\"\nmsgid \"$entry\"\nmsgstr \"\"\n"
208 ## Hmm, if civicrm_country.tpl used {ts}, then we could just call "civistrings --msgctxt=country"
211 ## Standard targets, sorted alphabetically
214 _civistrings
-o "$filepath" \
215 {CRM
,templates
/CRM
}/$name \
216 xml
/templates
/message_templates
/petition_
*
220 _civistrings
-o "$filepath" \
221 {CRM
,templates
/CRM
}/$name \
222 ang
/crmCaseType
{,.js
} \
223 xml
/templates
/message_templates
/case_
*
227 _civistrings
-o "$filepath" \
228 {CRM
,templates
/CRM
}/$name \
229 xml
/templates
/message_templates
/contribution_
* \
230 xml
/templates
/message_templates
/test_
*
234 _civistrings
-o "$filepath" \
235 {CRM
,templates
/CRM
}/$name \
236 xml
/templates
/message_templates
/event_
* \
237 xml
/templates
/message_templates
/participant_
*
241 _civistrings
-o "$filepath" \
242 {CRM
,templates
/CRM
}/$name \
243 ang
/crm
{Mailing
,MailingAB
}{,.js
}
247 _civistrings
-o "$filepath" \
248 {CRM
,templates
/CRM
}/$name \
249 xml
/templates
/message_templates
/membership_
*
253 _civistrings
-o "$filepath" \
254 {CRM
,templates
/CRM
}/$name \
255 xml
/templates
/message_templates
/pcp_
*
259 _civistrings
-o "$filepath" \
260 {CRM
,templates
/CRM
}/$name \
261 xml
/templates
/message_templates
/pledge_
*
265 if echo " $COMPONENT_POTS " |
grep -q " $name " > /dev
/null
; then
266 _civistrings
-o "$filepath" {CRM
,templates
/CRM
}/$name
268 echo "unrecognized pot: $name"
274 find "$filepath" ! -empty |
while read f
; do
275 msguniq
"$filepath" | sponge
"$filepath"
279 #####################################################################
280 ## usage: make_stat <name>
281 ## example: make_stat Mailing
282 function make_stat
() {
284 local filepath
="$POTDIR/.raw-"$
(echo $name |
tr '[:upper:]' '[:lower:]').pot
285 grep ^msgid
"$filepath" |
sort -u > "$filepath.msgid"
286 grep '^#:' "$filepath" |
sed 's/#://' |
tr ' ' '\n' |
sort -u > "$filepath.files"
289 #####################################################################
290 ## Scan .raw-*.pot for common strings and put them in common-components.pot
291 ## usage: build_common_components
292 function build_common_components
() {
293 echo "[[ Building common-components.pot ]]"
296 for comp
in $COMPONENT_POTS ; do
297 local rawfile
=".raw-"$
(echo $comp |
tr '[:upper:]' '[:lower:]').pot
298 if [ -f "$rawfile" ]; then
299 paths
="$paths $rawfile"
303 if [ $has_multiple -eq 1 ]; then
304 msgcomm
$paths > .raw-common-components.pot
306 cat $HEADER > .raw-common-components.pot
310 #####################################################################
311 ## example: build_final_pot Mailing
312 ## example: build_final_pot install
313 function build_final_pot
() {
315 local rawpath
="$POTDIR/.raw-"$
(echo $name |
tr '[:upper:]' '[:lower:]').pot
316 local finalpath
="$POTDIR/"$
(echo $name |
tr '[:upper:]' '[:lower:]').pot
317 local tmpfile
=`tempfile`
319 echo "[[ Building final strings for ${name} ]]"
321 cp -f "$rawpath" "$finalpath"
323 if echo " $COMPONENT_POTS " |
grep -q " $name " > /dev
/null
; then
324 msgcomm
"$finalpath" .raw-common-components.pot
> $tmpfile
325 msgcomm
--unique "$finalpath" $tmpfile | sponge
"$finalpath"
327 msgcomm
"$finalpath" .raw-common-base.pot | sponge
$tmpfile
328 msgcomm
--unique "$finalpath" $tmpfile | sponge
"$finalpath"
330 elif [ "$name" == "install" ]; then
331 msgcomm
"$finalpath" .raw-common-base.pot | sponge
$tmpfile
332 msgcomm
--unique "$finalpath" $tmpfile | sponge
"$finalpath"
338 #####################################################################
340 function do_cleanup
() {
341 echo "[[ Cleanup temp files ]]"
342 rm .header .raw
*pot
-f
345 #####################################################################
348 [ "$1" == "--help" ] && usage
349 [ "$1" == "-h" ] && usage
354 while getopts "asfdc" opt
; do
378 echo "Invalid option: -$OPTARG" >&2
382 echo "Option -$OPTARG requires an argument." >&2
388 if [ -z "$FOUND_ACTION" ]; then
396 [ "$1" == "" ] && echo 'source dir missing' && usage
397 test ! -e "$1" && echo 'source does not exist' && usage
398 test ! -d "$1" && echo 'source not a directory' && usage
400 [ "$2" == "" ] && echo 'target dir missing' && usage
401 test ! -e "$2" && echo 'target does not exist' && usage
402 test ! -d "$2" && echo 'target not a directory' && usage
404 # use absolute paths so that we can chdir/pushd
405 SRC
=$
(php
-r 'echo realpath($argv[1]);' "$1")
406 POTDIR
=$
(php
-r 'echo realpath($argv[1]);' "$2")
407 HEADER
=$
(build_header
"$HEADER_TMPL")
408 ## TODO: substitute "NOW" in HEADER
412 POTS
="$COMPONENT_POTS $ADHOC_POTS $MAGIC_POTS"
417 if [ -n "$DO_SCAN" ]; then
418 pushd "$SRC" >> /dev
/null
419 for POT
in $POTS ; do
425 if [ -n "$DO_DIGEST" ]; then
426 pushd "$POTDIR" >> /dev
/null
428 build_common_components
429 for POT
in $POTS ; do
430 echo "+++++++++ $POT"
431 build_final_pot
"$POT"
436 if [ -n "$DO_CLEANUP" ]; then
437 pushd "$POTDIR" >> /dev
/null