-
Notifications
You must be signed in to change notification settings - Fork 15
/
go
executable file
·346 lines (314 loc) · 9.39 KB
/
go
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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
#!/bin/bash
ansible_version=1.9.1
##### helper functions #####
autoinstall_wallah() {
[[ -f wallah/bin/install_iojs ]] && return
git submodule update --init --depth 1
}
autoinstall_npm_deps() {
autoinstall_wallah
./package.js optional
./wallah/bin/install_iojs "$(./wallah/bin/get_json_value package.json engines.iojs)"
[[ -d node_modules/mocha ]] && return
npm install
}
doc() {
help="${help}$1
"
}
#The "help" variable gets extended by the "doc" function
#inline below as needed sort of javadoc/python decorator style
help=""
usage() {
cat <<EOF
Usage: $(basename $0) <subcommand> [args…]
Purpose of $(basename $0) script
--------------------
* entrypoint script for common commands
* Automatically installs development prerequisites
* Ensures the correct PATH environment variable
* deals with node, npm, python, ansible, vagrant, etc
* commands are grouped by lifecycle and described in more detail below
${help}
EOF
}
doc "Development Commands
--------------------"
doc "* express: start the express server (also aliased as \"start\")"
task::express() {
autoinstall_npm_deps
node-dev --debug=9001 ./app/server.js | \
tee -a ./log/app.log | \
bistre
}
task::start() {
task::express "$@"
}
doc "* test [node|browser|debug]: run automated test suite and linting
* no args runs them all
* otherwise run the groups provided
* debug: run mocha tests with immediate breakpoint for debugging"
task::test() {
local groups="${@-node browser}"
for group in ${groups}; do
if type "test_${group}" &>/dev/null; then
eval "test_${group}"
else
usage "$0 test [node|browser|debug]"
return
fi
done
task::lint
}
test_node() {
set -e
echo "node.js mocha unit tests…"
autoinstall_npm_deps
echo -n "browserifying…"
task::bundle
echo ✓
export NODE_ENV=test
if [[ $# -eq 0 ]]; then
mocha $(find ./app -name \*.test.js -print0 | sort | xargs -0)
else
mocha "$@"
fi
echo ✓
}
test_browser() {
set +e
echo -n browser tests…
local browser="--phantom"
#use this for real browser
# local browser="--local $(config3 tests.port)"
zuul ${browser} --ui mocha-bdd --open \
$(find ./app -name '*btest.js' -print0 | xargs -0)
echo ✓
}
test_debug() {
autoinstall_npm_deps
NODE_ENV=test mocha --debug-brk=$(config3 tests.debugPort) "$@"
}
doc "* bundle: generate browser JS for development"
task::bundle() {
"${1-browserify}" \
-o www/plws.js \
--debug \
$(./bin/browserify_args.sh)
"${1-browserify}" \
-o www/plws.js \
--debug \
$(./bin/browserify_args.sh)
browserify -o www/reveal.js -e app/browser/deck
}
doc "* lint: enforce code style/quality with eslint"
task::lint() {
echo -n "linting…"
eslint --format ./node_modules/eslint-formatter-comment/index.js \
app bin
echo ✓
}
doc "* validate: Run W3C HTML5 validator against the site HTML"
task::validate() {
autoinstall_npm_deps
NODE_ENV=test ./bin/validate.js
}
doc "* shrinkwrap: regenerate npm-shrinkwrap.json file"
task::shrinkwrap() {
rm npm-shrinkwrap.json
./package.js production
npm prune
#Need to restore the node_modules/app symlink
git checkout node_modules
npm shrinkwrap
}
doc "* errors: regenerate static error HTML pages"
task::errors() {
autoinstall_wallah
./wallah/bin/check_prerequisites curl
local devurl="http://localhost:9000"
local static="../static"
echo "Generating HTML for static error pages from ${devurl}..."
for uri in error404 error500; do
local url="${devurl}/${uri}"
echo -n "${uri}, "
local exit_code=0
curl --silent "${url}" --output \
"${static}/${uri}.html" || exit_code=$?
if [ ${exit_code} -ne 0 ]; then
echo "FAILED to retrieve ${url}"
exit ${exit_code}
fi
done
}
doc "
Deployment Commands
-------------------"
doc "* clean: delete the build directory"
task::clean() {
rm -rf ./build ./www/*
}
doc "* release_candidate: begin git work to prepare for a build/test/release
* (aliased as "rc")
* Usage: $(basename $0) release_candidate <patch|minor|major>"
task::release_candidate() {
autoinstall_npm_deps
./wallah/bin/check_prerequisites git
echo "Creating a new release candidate"
git checkout develop
git pull origin develop
bump _package.json --"${1-patch}"
local version=$(config3 appVersion)
git add _package.json
git commit -m "bump version for ${version} release"
git tag "v${version}"
cat <<-EOF
Ready
Next steps are:
go build v${version}
deploy to stage
test on stage
go release
deploy to prod
EOF
}
task::rc() {
task::release_candidate "$@"
}
doc "* build: build a distribution archive for deployment
* Usage: $(basename $0) build <HEAD|WORK|TAG>
* $(basename $0) build HEAD will use the last commit on the current branch
* $(basename $0) build WORK will use uncommited local changes
* $(basename $0) build TAG will use the code in the given git tag"
task::build() {
set -e
echo -n "prereqs…"
autoinstall_wallah
./wallah/bin/check_prerequisites git tar curl
autoinstall_npm_deps
#need the build system python here
export PATH=/usr/bin:$PATH
local git_ref="${1-HEAD}"
local build_dir="build"
local prefix="peterlyons.com-${git_ref}-$(date +%Y%m%d%H%M)"
mkdir -p "${build_dir}/${prefix}/node"
echo ✓; echo -n "git archive…"
#note we need to use "-C" with tar and not "--directory" due to bsdtar on osx
if [[ "${git_ref}" == "WORK" ]]; then
git ls-files \
| tar -T - --create --file - \
| tar -C "${build_dir}/${prefix}" --extract --file -
else
git archive --format=tar --prefix="${prefix}/" "${git_ref}" | \
#extract that archive into a temporary build directory
tar -C "${build_dir}" --extract
fi
#install node
echo ✓; echo -n "node…"
local node_version="$(./wallah/bin/get_json_value package.json engines.iojs)"
local iojs_archive="iojs-v${node_version}-linux-x86.tar.gz"
local iojs_url=$(echo "https://iojs.org/dist/v" \
"${node_version}/iojs-v${node_version}-linux-x86.tar.gz" | tr -d " ")
if [[ ! -f "${iojs_archive}" ]]; then
curl --silent --remote-name "${iojs_url}"
fi
echo ✓; echo -n "npm packages…"
tar -C "${build_dir}/${prefix}/node" --strip-components=1 --extract --gzip \
--file "${iojs_archive}"
cd "${build_dir}/${prefix}"
# Run OSX node and npm utilites but within the linux build dir
./package.js build
# npm-pkgr --strategy=copy --production --silent --parseable &> "../npm.log"
npm install
bower install --production
./bin/build_js.sh
npm dedupe
./package.js production
npm prune --production
# npm prune removes our symlink, add it back
ln -nsf ../app node_modules/app
#remove development-only files
rm -rf wallah doc deploy test Vagrantfile .gitignore .agignore .gitmodules
find ./app -name \*.test.js | xargs rm
cd -
echo ✓; echo -n "vagrant rebuild…"
./bin/go vagrant ssh build -c \
"'cd /vagrant/${build_dir}/${prefix} && ./node/bin/npm rebuild --silent --parseable &>> ../npm.log'"
echo ✓; echo -n "archive…"
local dist_path="${build_dir}/${prefix}.tar.gz"
tar -C "${build_dir}" --create --gzip --file "${dist_path}" "${prefix}"
echo ✓
ls -lh "${dist_path}"
echo "To deploy to stage, run:"
echo " ./bin/go deploy ${dist_path} deploy/hosts/vagrant_stage.yml"
}
doc "* deploy: deploy code to a target system via ansible
* Usage: $(basename $0) deploy <dist-file> <inventory-file>
* will deploy the full stack to the server(s) listed in the ansible yaml inventory file argument
* distribution archive files get built in the "build" directory
* inventory files live in the deploy/hosts directory"
task::deploy() {
set -e
autoinstall_wallah
./wallah/bin/install_pip_package ansible
local dist_path="$1"
local dist_name=$(basename "${dist_path/.tar.*/}")
local inventory="$2"
export ANSIBLE_HOST_KEY_CHECKING=False
ansible-playbook \
-i "${inventory}" \
--ask-sudo-pass \
--extra-vars "dist=${dist_path}" \
--extra-vars "dist_name=${dist_name}" \
./deploy/playbook_full_stack.yml
}
doc "* release: merge develop to master and push tags for a release"
task::release() {
autoinstall_wallah
./wallah/bin/check_prerequisites git
git checkout develop
git pull origin develop
task::test
echo "Will merge develop to master and push to origin"
echo "CTRL-C now to abort. ENTER to proceed."
read DONTCARE
git checkout master
git merge develop
git push origin master --tags
git checkout develop #Not good form to leave master checked out
echo "Done. Miller Time."
}
doc "* vagrant: convenience wrapper for vagrant commands
* autoinstalls deps"
task::vagrant() {
autoinstall_wallah
./wallah/bin/install_pip_package "ansible=${ansible_version}"
exec vagrant "$@"
}
doc "* ansible-playbook: convenience wrapper around ./python/bin/ansible-playbook
* used for running ad hoc ansible commands
* installs ansible if needed
* arguments are passed through to ./python/bin/ansible"
task::ansible-playbook() {
autoinstall_wallah
./wallah/bin/install_pip_package "ansible=${ansible_version}"
ANSIBLE_HOST_KEY_CHECKING=False exec ansible-playbook "$@"
}
##### main code #####
main() {
cd "$(dirname "$0")/.."
PATH="${PATH}:${PWD}/python/bin"
PATH="${PATH}:${PWD}/node/bin"
PATH="${PATH}:${PWD}/node_modules/.bin"
#Need the basics like dirname et al
PATH="${PATH}:/usr/bin:/bin"
export PATH
task_name="$1"
if type "task::${task_name}" &>/dev/null; then
shift
eval "task::${task_name}" "$@"
else
usage "$@"
fi
}
main "$@"