forked from dimagi/commcare-hq
-
Notifications
You must be signed in to change notification settings - Fork 0
/
externalize_js.sh
executable file
·205 lines (168 loc) · 7.08 KB
/
externalize_js.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#!/bin/sh
# PURPOSE:
# Externalizing JS is a fairly manual process that has to happen
# on a couple hundred files. Hopefully this will simplify that process
# It creates a new file, places whatever was in the js-inline
# script tags in the new file, and adds the new necessary static import
# to the html file. This is then committed.
# Afterwards it checks for django template tags, deletes and replaces them
# with a few functions and prints out the newly needed initial_page_data tags
# USAGE:
# From the base level of this repo, run `./scripts/externalize_js.sh <app> <module>
# The first argument is the django app the module is located in.
# The second is the file name of the module.
# ex. `$ ./scripts/externalize_js.sh sms add_gateway`
# It isn't perfect, definitely check for lint and adjust the names around as desired.
# There are also a few lines printed by the script that may need to be placed in the code as directed
# Also make sure to visit the page(s) the module is used on to make sure they aren't borked!.
# strict mode --> kill it if something fails
set -euo pipefail
function abort () {
echo $1
echo "Aborting."
exit 1
}
function should_continue () {
select yn in "Yes" "No"; do
case $yn in
Yes ) break;;
No ) abort "Sounds good.";;
esac
done
}
# GNU-sed is apparently much more powerful than the OSX standard,
# and there is at least one place where it's quite useful.
# Some regexes below won't function correctly without it.
has_gnu_sed=`sed --version | grep "GNU sed"`
if [[ ! $has_gnu_sed ]]; then
echo "Hey! This script was written using GNU sed so it may not function quite as expected using your setup."
echo "If you want to install GNU sed, please visit this link http://bfy.tw/GbIs"
echo "Do you want to run the rest of the script anyway?"
should_continue
fi
has_local_changes=`git diff-index HEAD` && true
if [[ $has_local_changes ]]; then
abort "You have uncommitted changes in your working tree."
fi
APP=$1
MODULE=$2
branch=$(git rev-parse --abbrev-ref HEAD)
if [[ $branch == 'master' ]]; then
echo "You must not be on master to run this command."
echo "Create a new branch?"
function branch() {
read -p "What are your initials?" INITIALS
git checkout -b $INITIALS/ejs/$APP-$MODULE
}
select yn in "Yes" "No"; do
case $yn in
Yes ) branch; break;;
No ) abort "You must not be on master to run this command."
esac
done
fi
# formulate locations and names
HTML_FILE_LOCATION="./corehq/apps/$APP/templates/$APP/$MODULE.html"
NEW_MODULE_NAME="$APP/js/$MODULE"
NEW_MODULE_LOCATION="./corehq/apps/$APP/static/$APP/js/$MODULE.js"
EXISTENT_MODULE=false
if [ -f $NEW_MODULE_LOCATION ]; then
echo "The new module has already been created.\nDo you want to continue?"
should_continue
EXISTENT_MODULE=true
fi
if [ "$EXISTENT_MODULE" == true ]; then
# delete the last line, opening up the module for more code
sed -i "$ d" $NEW_MODULE_LOCATION
else
# create file
mkdir -p ./corehq/apps/$APP/static/$APP/js && touch $NEW_MODULE_LOCATION
# add boilerplate
echo "hqDefine('$NEW_MODULE_NAME', function() {" >> $NEW_MODULE_LOCATION
fi
if [ "$EXISTENT_MODULE" == false ]; then
# add import to the html
SCRIPT_IMPORT="<script src=\"{% static '$NEW_MODULE_NAME.js' %}\"></script>"
count=$(sed -n "/{% block js %}/p" $HTML_FILE_LOCATION | wc -l)
# if there is a block js, add it inside at the end
if [ "$count" -gt 0 ]; then
sed -i "/{% block js %}/,/{% endblock/ {
/{% endblock/ i \\
$SCRIPT_IMPORT
}" $HTML_FILE_LOCATION
# otherwise, just tell them to add one somewhere on the page
else
sed -i "/{% block js-inline %}/i \
{% block js %}{{ block.super }}\n\t$SCRIPT_IMPORT\n{% endblock %}" $HTML_FILE_LOCATION
fi
fi
# pull inline js from file, removes the script tags, and places it into the new file
sed -n "/{% block js-inline %}/, /{% endblock\( js-inline\)\? %}/ p" $HTML_FILE_LOCATION | \
python -c "import sys; sys.stdout.writelines(sys.stdin.readlines()[2:-2])" >> $NEW_MODULE_LOCATION
# remove from old file
sed -i "/{% block js-inline %}/, /{% endblock\( js-inline\)\? %}/ d" $HTML_FILE_LOCATION
# close off boilerplate
echo "});" >> $NEW_MODULE_LOCATION
# fix eslint issues
echo "Fixing lint issues"
eslint --fix $NEW_MODULE_LOCATION || true
# commit the blob movement
git add $NEW_MODULE_LOCATION $HTML_FILE_LOCATION
git commit -m "first pass externalizing javascript in $MODULE"
# check where in page there are template tags
OPEN_BRACKET_REGEX="{\(%\|{\)"
CLOSE_BRACKET_REGEX="\(%\|}\)}"
QUOTE="\('\|\"\)"
TEMPLATE_TAGS=`sed -n "/$OPEN_BRACKET_REGEX/=" $NEW_MODULE_LOCATION`
TEMPLATE_TAG_COUNT=`echo $TEMPLATE_TAGS | wc -w`
if [ "$TEMPLATE_TAG_COUNT" -gt 0 ]; then
echo "----------------------------"
echo "Please check template tags on these lines."
echo $TEMPLATE_TAGS
# convert translation tags first
GETTEXT_OPEN="gettext("
GETTEXT_CLOSE=")"
sed -i "/$QUOTE$OPEN_BRACKET_REGEX trans/s/ $CLOSE_BRACKET_REGEX$QUOTE/$GETTEXT_CLOSE/; \
s/$QUOTE$OPEN_BRACKET_REGEX trans /$GETTEXT_OPEN/" $NEW_MODULE_LOCATION
# now move on to tags that require imports
INITIALPAGEDATA_OPEN="initialPageData.get('"
INITIAL_PAGE_DATA_CLOSE="')"
INITIAL_PAGE_DATA_TAGS=`sed -n "s/.*$OPEN_BRACKET_REGEX//; s/ $CLOSE_BRACKET_REGEX.*//p" $NEW_MODULE_LOCATION`
INITIAL_PAGE_DATA_TAG_LINES=`sed -n "/$OPEN_BRACKET_REGEX/=" $NEW_MODULE_LOCATION`
TAG_COUNT=`echo $INITIAL_PAGE_DATA_TAGS | wc -w`
if [ "$TAG_COUNT" -gt 0 ]; then
sed -i "s/$OPEN_BRACKET_REGEX /$INITIALPAGEDATA_OPEN/; \
s/ $CLOSE_BRACKET_REGEX/$INITIAL_PAGE_DATA_CLOSE/" $NEW_MODULE_LOCATION
INITIALPAGEDATA_IMPORT="var initialPageData = hqImport('hqwebapp\/js\/initial_page_data')\;"
sed -i "/hqDefine/a \
$INITIALPAGEDATA_IMPORT" $NEW_MODULE_LOCATION
echo "and in particular these lines"
echo $INITIAL_PAGE_DATA_TAG_LINES
PAGE_CONTENT=`sed -n "/block page_content/=" $HTML_FILE_LOCATION`
PAGE_CONTENT_WORDS=`echo $INITIAL_PAGE_DATA_TAGS | wc -w`
if [ "$PAGE_CONTENT_WORDS" -gt 0 ]; then
IFS=$'\n'
for ipd in $INITIAL_PAGE_DATA_TAGS; do
sed -i "/block page_content/a\
{% initial_page_data '$ipd' $ipd %}" $HTML_FILE_LOCATION
done
else
echo "and add these data imports as well"
for ipd in $INITIAL_PAGE_DATA_TAGS; do
echo "{% initial_page_data '$ipd' $ipd %}"
done
fi
fi
git add $NEW_MODULE_LOCATION $HTML_FILE_LOCATION
git commit -m "initial page data"
echo "----------------------------"
fi
# fix eslint issues
echo "Maybe fixing more lint issues"
eslint --fix $NEW_MODULE_LOCATION || true
# a bit more yelling at the user
# (maybe should just open these in an available browser? todo)
./manage.py show_urls | grep $MODULE
echo "----------------------------"
echo "^^^^^^ Check to see if this/these page(s) works"
echo "----------------------------"