#!/usr/bin/env bash # exit on errors set -e # check if we're in DEBUG mode DEBUG=$(sed <.env -ne 's/^DEBUG=//p') # disallow certain commands when debug is false function prod_error { if [ "$DEBUG" != "true" ]; then echo "This command is not safe to run in production environments" exit 1 fi } # import our ENV variables # catch exits and give a friendly error message function showerr { echo "Failed to load configuration! You may need to update your .env and quote values with special characters in them." } trap showerr EXIT source .env trap - EXIT if docker compose &> /dev/null ; then DOCKER_COMPOSE="docker compose" else DOCKER_COMPOSE="docker-compose" fi function clean { $DOCKER_COMPOSE stop $DOCKER_COMPOSE rm -f } function runweb { $DOCKER_COMPOSE run --rm web "$@" } function execdb { $DOCKER_COMPOSE exec db $@ } function execweb { $DOCKER_COMPOSE exec web "$@" } function initdb { runweb python manage.py initdb "$@" } function migrate { runweb python manage.py migrate "$@" } function admin_code { runweb python manage.py admin_code } function awscommand { # expose env vars export AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} export AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} export AWS_DEFAULT_REGION=${AWS_S3_REGION_NAME} # first arg is mountpoint, second is the whole aws command docker run --rm -it -v $1\ -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e AWS_DEFAULT_REGION\ amazon/aws-cli $2 } CMD=$1 if [ -n "$CMD" ]; then shift fi # show commands as they're executed set -x case "$CMD" in up) $DOCKER_COMPOSE up --build "$@" ;; down) $DOCKER_COMPOSE down ;; service_ports_web) prod_error $DOCKER_COMPOSE run --rm --service-ports web ;; initdb) initdb "$@" ;; resetdb) prod_error $DOCKER_COMPOSE rm -svf docker volume rm -f bookwyrm_media_volume bookwyrm_pgdata bookwyrm_redis_activity_data bookwyrm_redis_broker_data bookwyrm_static_volume $DOCKER_COMPOSE build migrate migrate django_celery_beat initdb runweb python manage.py compile_themes runweb python manage.py collectstatic --no-input admin_code ;; makemigrations) prod_error runweb python manage.py makemigrations "$@" ;; migrate) migrate "$@" ;; bash) runweb bash ;; shell) runweb python manage.py shell ;; dbshell) execdb psql -U ${POSTGRES_USER} ${POSTGRES_DB} ;; restart_celery) $DOCKER_COMPOSE restart celery_worker ;; pytest) prod_error runweb pytest --no-cov-on-fail "$@" ;; pytest_coverage_report) prod_error runweb pytest -n 3 --cov-report term-missing "$@" ;; compile_themes) runweb python manage.py compile_themes ;; collectstatic) runweb python manage.py collectstatic --no-input ;; makemessages) prod_error runweb django-admin makemessages --no-wrap --ignore=venv -l en_US $@ ;; compilemessages) runweb django-admin compilemessages --ignore venv $@ ;; update_locales) prod_error git fetch origin l10n_main:l10n_main git checkout l10n_main locale/ca_ES git checkout l10n_main locale/de_DE git checkout l10n_main locale/eo_UY git checkout l10n_main locale/es_ES git checkout l10n_main locale/eu_ES git checkout l10n_main locale/fi_FI git checkout l10n_main locale/fr_FR git checkout l10n_main locale/gl_ES git checkout l10n_main locale/ko_KR git checkout l10n_main locale/it_IT git checkout l10n_main locale/lt_LT git checkout l10n_main locale/nl_NL git checkout l10n_main locale/no_NO git checkout l10n_main locale/pl_PL git checkout l10n_main locale/pt_PT git checkout l10n_main locale/pt_BR git checkout l10n_main locale/ro_RO git checkout l10n_main locale/sv_SE git checkout l10n_main locale/uk_UA git checkout l10n_main locale/zh_Hans git checkout l10n_main locale/zh_Hant runweb django-admin makemessages --no-wrap --ignore=venv -l en_US $@ runweb django-admin compilemessages --ignore venv ;; build) $DOCKER_COMPOSE build ;; clean) prod_error clean ;; black) prod_error $DOCKER_COMPOSE run --rm dev-tools black celerywyrm bookwyrm ;; pylint) prod_error # pylint depends on having the app dependencies in place, so we run it in the web container runweb pylint bookwyrm/ ;; prettier) prod_error $DOCKER_COMPOSE run --rm dev-tools prettier --write bookwyrm/static/js/*.js ;; eslint) prod_error $DOCKER_COMPOSE run --rm dev-tools eslint bookwyrm/static --ext .js ;; stylelint) prod_error $DOCKER_COMPOSE run --rm dev-tools stylelint --fix bookwyrm/static/css \ --config dev-tools/.stylelintrc.js --ignore-path dev-tools/.stylelintignore ;; formatters) prod_error runweb pylint bookwyrm/ $DOCKER_COMPOSE run --rm dev-tools black celerywyrm bookwyrm $DOCKER_COMPOSE run --rm dev-tools prettier --write bookwyrm/static/js/*.js $DOCKER_COMPOSE run --rm dev-tools eslint bookwyrm/static --ext .js $DOCKER_COMPOSE run --rm dev-tools stylelint --fix bookwyrm/static/css \ --config dev-tools/.stylelintrc.js --ignore-path dev-tools/.stylelintignore ;; mypy) prod_error runweb mypy celerywyrm bookwyrm ;; collectstatic_watch) prod_error npm run --prefix dev-tools watch:static ;; update) git pull $DOCKER_COMPOSE build # ./update.sh runweb python manage.py migrate runweb python manage.py compile_themes runweb python manage.py collectstatic --no-input $DOCKER_COMPOSE up -d $DOCKER_COMPOSE restart web $DOCKER_COMPOSE restart celery_worker ;; populate_streams) runweb python manage.py populate_streams "$@" ;; populate_lists_streams) runweb python manage.py populate_lists_streams $@ ;; populate_suggestions) runweb python manage.py populate_suggestions ;; generate_thumbnails) runweb python manage.py generateimages ;; generate_preview_images) runweb python manage.py generate_preview_images "$@" ;; remove_remote_user_preview_images) runweb python manage.py remove_remote_user_preview_images ;; erase_deleted_user_data) runweb python manage.py erase_deleted_user_data "$@" ;; copy_media_to_s3) awscommand "bookwyrm_media_volume:/images"\ "s3 cp /images s3://${AWS_STORAGE_BUCKET_NAME}/images\ --endpoint-url ${AWS_S3_ENDPOINT_URL}\ --recursive --acl public-read" "$@" ;; sync_media_to_s3) awscommand "bookwyrm_media_volume:/images"\ "s3 sync /images s3://${AWS_STORAGE_BUCKET_NAME}/images\ --endpoint-url ${AWS_S3_ENDPOINT_URL}\ --acl public-read" "$@" ;; set_cors_to_s3) set +x config_file=$1 if [ -z "$config_file" ]; then echo "This command requires a JSON file containing a CORS configuration as an argument" exit 1 fi set -x awscommand "$(pwd):/bw"\ "s3api put-bucket-cors\ --bucket ${AWS_STORAGE_BUCKET_NAME}\ --endpoint-url ${AWS_S3_ENDPOINT_URL}\ --cors-configuration file:///bw/$config_file" "$@" ;; admin_code) admin_code ;; setup) migrate migrate django_celery_beat initdb runweb python manage.py compile_themes runweb python manage.py collectstatic --no-input admin_code ;; runweb) runweb "$@" ;; remove_2fa) runweb python manage.py remove_2fa "$@" ;; confirm_email) runweb python manage.py confirm_email "$@" ;; *) set +x # No need to echo echo echo "Unrecognised command. Try:" echo " setup" echo " up [container]" echo " down" echo " service_ports_web" echo " initdb" echo " resetdb" echo " makemigrations [migration]" echo " migrate [migration]" echo " bash" echo " shell" echo " dbshell" echo " restart_celery" echo " pytest [path]" echo " compile_themes" echo " collectstatic" echo " makemessages" echo " compilemessages [locale]" echo " update_locales" echo " build" echo " clean" echo " black" echo " prettier" echo " eslint" echo " stylelint" echo " formatters" echo " mypy" echo " collectstatic_watch" echo " populate_streams [--stream=<stream name>]" echo " populate_lists_streams" echo " populate_suggestions" echo " generate_thumbnails" echo " generate_preview_images [--all]" echo " remove_remote_user_preview_images" echo " copy_media_to_s3" echo " sync_media_to_s3" echo " set_cors_to_s3 [cors file]" echo " runweb [command]" echo " remove_2fa" echo " confirm_email" ;; esac