forked from uccser/cs-unplugged
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcsu
executable file
·457 lines (397 loc) · 12.3 KB
/
csu
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
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
#!/bin/bash
# Helper script for commands related to the CS Unplugged repository.
#
# Notes:
# - Changes to template only require user to refresh browser.
# - Changes to static files require the 'static' command to be run.
# - Changes to Python code are detected by gunicorn and should take effect
# on the server after a few seconds.
#
# Future plans:
# - Start systems when a command is given (for example: 'static') when the
# development system has not yet been started.
# - When 'start' is run open website in default browser without creating
# new terminal prompt.
set -e
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
cmd_helps=()
defhelp() {
local command="${1?}"
local text="${2?}"
local help_str
help_str="$(printf ' %-24s %s' "$command" "$text")"
cmd_helps+=("$help_str")
}
# Print out help information
cmd_help() {
echo "Script for performing tasks related to the CS Unplugged repository."
echo
echo "Usage: ./csu [COMMAND]"
echo "Replace [COMMAND] with a word from the list below."
echo
echo "COMMAND list:"
for str in "${cmd_helps[@]}"; do
echo -e "$str"
done
}
defhelp help 'View all help.'
# Start development environment
cmd_start() {
echo "Creating systems..."
docker-compose up -d
echo ""
# Alert user that system is ready
echo -e "\n${GREEN}System is up!${NC}"
echo "Run the command ./csu update to load content."
}
defhelp start 'Start development environment (this also runs the update command).'
# Stop development environment
cmd_end() {
echo "Stopping systems... (takes roughly 10 to 20 seconds)"
docker-compose down
echo
echo "Deleting system volumes..."
volumes=($(docker volume ls -qf dangling=true ))
for volume in "${volumes[@]}"; do
docker volume rm "${volume}"
done
}
defhelp end 'Stop development environment.'
cmd_restart() {
cmd_end
cmd_start
}
defhelp restart 'Stop and then restart development environment.'
# Run Django migrate and updatedata commands
cmd_update() {
cmd_static
echo ""
cmd_migrate
echo ""
cmd_updatedata
cmd_rebuild_index
cmd_static_scratch
echo ""
cmd_makeresourcethumbnails
cmd_collect_static
echo ""
echo -e "\n${GREEN}Content is loaded!${NC}"
echo "Open your preferred web browser to the URL 'localhost'"
}
defhelp update 'Run Django migrate and updatedata commands and build static files.'
# Run update command only for key content
cmd_update_lite() {
cmd_static
echo ""
cmd_migrate
echo ""
echo "Loading content..."
docker-compose exec django /docker_venv/bin/python3 ./manage.py updatedata --lite-load
cmd_collect_static
echo ""
echo -e "\n${GREEN}Key content is loaded!${NC}"
echo "Run the 'update' command to load all content"
echo "Open your preferred web browser to the URL 'localhost'"
}
defhelp update_lite 'Run update command only for key content - Useful for development.'
# Collecting static files
cmd_collect_static() {
echo
echo "Collecting static files..."
docker-compose exec django /docker_venv/bin/python3 ./manage.py collectstatic --no-input --clear
}
defhelp collect_static "Collecting static files."
# Update and collect static files
cmd_update_static() {
cmd_static
echo ""
cmd_collect_static
echo ""
echo -e "\n${GREEN}Static files are updated!${NC}"
}
defhelp update_static 'Update and collect static files.'
# Run Django flush command
cmd_flush() {
docker-compose exec django /docker_venv/bin/python3 ./manage.py flush
}
defhelp flush 'Run Django flush command.'
# Run Django makemigrations command
cmd_makemigrations() {
echo "Creating database migrations..."
docker-compose exec django /docker_venv/bin/python3 ./manage.py makemigrations --no-input
}
defhelp makemigrations 'Run Django makemigrations command.'
# Run Django makeresources command
cmd_makeresources() {
echo "Creating static resource PDFs..."
docker-compose exec django /docker_venv/bin/python3 ./manage.py makeresources
}
defhelp makeresources 'Run Django makeresources command.'
# Run Django makeresourcethumbnails command
cmd_makeresourcethumbnails() {
echo "Creating thumbnails for resource PDFs..."
docker-compose exec django /docker_venv/bin/python3 ./manage.py makeresourcethumbnails
}
defhelp makeresourcethumbnails 'Run Django makeresourcethumbnails command.'
# Run Django makemessages command
cmd_makemessages() {
echo "Creating message files..."
docker-compose exec django /docker_venv/bin/python3 ./manage.py makemessages -l en
}
defhelp makemessages 'Run Django makemessages command.'
# Run Django compilemessages command
cmd_compilemessages() {
echo "Compiling message files..."
docker-compose exec django /docker_venv/bin/python3 ./manage.py compilemessages
}
defhelp compilemessages 'Run Django compilemessages command.'
# Run Django migrate command
cmd_migrate() {
echo "Applying database migrations..."
docker-compose exec django /docker_venv/bin/python3 ./manage.py migrate
}
defhelp migrate 'Run Django migrate command.'
# Run Django updatedata command
cmd_updatedata() {
echo "Loading content..."
docker-compose exec django /docker_venv/bin/python3 ./manage.py updatedata
}
defhelp updatedata 'Run updatedata command.'
# Run Django loadactivities command
cmd_loadactivities() {
echo "Loading activities..."
docker-compose exec django /docker_venv/bin/python3 ./manage.py loadactivities
}
defhelp loadactivities 'Run loadactivities command.'
# Build Docker images
cmd_build() {
echo "Building Docker images..."
docker-compose build
}
defhelp build 'Build or rebuild Docker images.'
# Build static files
cmd_static() {
echo "Building static files..."
docker-compose exec nginx gulp build
}
defhelp static 'Build static files.'
# Build production static files
cmd_static_prod() {
echo "Building production static files..."
docker-compose exec nginx gulp build --production
}
defhelp static_prod 'Build production static files.'
# Build scratch static files
cmd_static_scratch() {
echo "Building scratch images..."
docker-compose exec nginx gulp scratch
}
defhelp static_scratch "Build scratch images."
# Run Django command rebuild_index
cmd_rebuild_index() {
echo "Rebuilding search index..."
docker-compose exec django /docker_venv/bin/python3 ./manage.py rebuild_index --noinput
}
defhelp rebuild_index "Run Django rebuild_index command."
# Run shell
cmd_shell() {
docker-compose exec django bash
}
defhelp shell "Open shell to Django folder."
# Run shell
cmd_django_shell() {
docker-compose exec django /docker_venv/bin/python3 ./manage.py shell
}
defhelp django_shell "Open Django shell."
# Reboot Django Docker container
cmd_reboot_django() {
echo "Rebooting Django Docker container..."
docker-compose restart django
}
defhelp reboot_django 'Reboot Django Docker container.'
# Run style checks
cmd_style() {
echo "Running PEP8 style checker..."
docker-compose exec django /docker_venv/bin/flake8
pep8_status=$?
echo
echo "Running Python docstring checker..."
docker-compose exec django /docker_venv/bin/pydocstyle --count --explain
pydocstyle_status=$?
! (( pep8_status || pydocstyle_status ))
}
defhelp style 'Run style checks.'
# Run test suite
cmd_test_suite() {
echo "Running test suite..."
docker-compose exec django /docker_venv/bin/coverage run --rcfile=/cs-unplugged/.coveragerc ./manage.py test --settings=config.settings.testing --pattern "test_*.py" -v 3 --nomigrations
}
defhelp test_suite 'Run test suite with code coverage.'
# Run specific test suite
cmd_test_specific() {
echo "Running specific test suite..."
docker-compose exec django /docker_venv/bin/python3 ./manage.py test --settings=config.settings.testing "${1}" -v 3 --nomigrations
}
defhelp test_specific 'Run specific test suite. Pass in parameter of Python test module.'
# Display test coverage table
cmd_test_coverage() {
echo "Displaying test suite coverage..."
docker-compose exec django /docker_venv/bin/coverage xml -i
docker-compose exec django /docker_venv/bin/coverage report -m --skip-covered
}
defhelp test_coverage 'Display code coverage report.'
# Run test suite backwards for CI testing
cmd_test_backwards() {
echo "Running test suite backwards..."
docker-compose exec django /docker_venv/bin/python3 ./manage.py test --settings=config.settings.testing --pattern "test_*.py" --reverse -v 0 --nomigrations
}
defhelp test_backwards 'Run test suite backwards.'
cmd_createsuperuser() {
docker-compose exec django /docker_venv/bin/python3 ./manage.py createsuperuser
}
defhelp createsuperuser "Create superuser in Django system."
# Generates the documentation (with warnings as errors)
cmd_docs() {
echo "Removing any existing documentation..."
docker-compose exec django rm -rf /cs-unplugged/docs/build/
docker-compose exec django mkdir /cs-unplugged/docs/build/
echo
echo "Creating documentation..."
docker-compose exec django /docker_venv/bin/sphinx-build -W /cs-unplugged/docs/source/ /cs-unplugged/docs/build/
}
defhelp docs 'Generate documentation.'
# Delete all untagged dangling Docker images
cmd_clean() {
echo "If the following commands return an argument not found error,"
echo "this is because there is nothing to delete for clean up."
echo
echo "Deleting unused volumes..."
unused_volumes=($(docker volume ls -qf dangling=true))
for vol in "${unused_volumes[@]}"; do
docker volume rm "${vol}"
done
echo
echo "Deleting exited containers..."
exited_containers=($(docker ps --filter status=dead --filter status=exited -aq))
for container in "${exited_containers[@]}"; do
docker rm -v "${container}"
done
echo
echo "Deleting dangling images..."
dangling_images=($(docker images -f "dangling=true" -q))
if [[ ${#dangling_images[@]} -gt 0 ]]; then
docker rmi "${dangling_images[@]}"
fi
}
defhelp clean 'Delete unused Docker files.'
# Delete all Docker containers and images
cmd_wipe() {
docker ps -a -q | xargs docker rm
docker images -q | xargs docker rmi
}
defhelp wipe 'Delete all Docker containers and images.'
# View logs
cmd_logs() {
docker-compose logs
}
defhelp logs 'View logs.'
ci_test_general() {
cmd_static
cmd_collect_static
docker-compose exec django /docker_venv/bin/coverage run --rcfile=/cs-unplugged/.coveragerc ./manage.py test --settings=config.settings.testing --pattern "test_*.py" -v 3 --exclude-tag=resource --exclude-tag=management --nomigrations
test_status=$?
cmd_test_coverage
coverage_status=$?
bash <(curl -s https://codecov.io/bash)
! (( $test_status || $coverage_status ))
}
ci_test_resources() {
cmd_static
cmd_collect_static
docker-compose exec django /docker_venv/bin/coverage run --rcfile=/cs-unplugged/.coveragerc ./manage.py test --settings=config.settings.testing --pattern "test_*.py" -v 3 --tag=resource --nomigrations
test_status=$?
cmd_test_coverage
coverage_status=$?
bash <(curl -s https://codecov.io/bash)
! (( $test_status || $coverage_status ))
}
ci_test_management() {
cmd_static
cmd_collect_static
docker-compose exec django /docker_venv/bin/coverage run --rcfile=/cs-unplugged/.coveragerc ./manage.py test --settings=config.settings.testing --pattern "test_*.py" -v 3 --tag=management --nomigrations
test_status=$?
cmd_test_coverage
coverage_status=$?
bash <(curl -s https://codecov.io/bash)
! (( $test_status || $coverage_status ))
}
ci_style() {
cmd_style
}
ci_test_backwards() {
cmd_static
cmd_collect_static
cmd_test_backwards
}
ci_docs() {
cmd_docs
}
ci_load_content() {
cmd_update
}
cmd_ci() {
cmd_start
local cmd="$1"
shift
if [ -z "$cmd" ]; then
echo -e "${RED}ERROR: ci command requires one parameter!${NC}"
cmd_help
exit 1
fi
if silent type "ci_$cmd"; then
"ci_$cmd" "$@"
exit $?
else
echo -e "${RED}ERROR: Unknown command!${NC}"
echo "Type './csu help' for available commands."
return 1
fi
}
silent() {
"$@" > /dev/null 2>&1
}
cmd_dev() {
local cmd="$1"
shift
if [ -z "$cmd" ]; then
echo -e "${RED}ERROR: command requires one parameter!${NC}"
cmd_help
return 1
fi
if silent type "cmd_$cmd"; then
"cmd_$cmd" "$@"
exit $?
else
echo -e "${RED}ERROR: Unknown command!${NC}"
echo "Type './csu help' for available commands."
return 1
fi
}
# If no command given
if [ $# -eq 0 ]; then
echo -e "${RED}ERROR: This script requires a command!${NC}"
cmd_help
exit 1
fi
cmd="$1"
shift
if silent type "cmd_$cmd"; then
"cmd_$cmd" "$@"
exit $?
else
echo -e "${RED}ERROR: Unknown command!${NC}"
echo "Type './csu help' for available commands."
exit 1
fi