#!/bin/bash # devctl is an utility script for automating some development tasks and actions. # To find out what options are available, run it without any arguments. # Text styles RED='\033[0;31m' BOLD=$(tput bold) NORMAL=$(tput sgr0) # Docker aliases misago_run="docker-compose run --rm misago" # Define dev paths # Those are paths to dirs and files created for dev project dev_paths=( "./avatargallery" "./devproject" "./media" "./static" "./theme" "./userdata" "./cron.txt" "./manage.py" ) # Required ports # Some tasks test for those ports before continuing port_django=8000 port_postgresql=5432 required_ports=($port_postgresql) # Default superuser username="Admin" password="password" # Some commond shorthands docker_stop() { docker-compose stop } docker_rebuild() { docker_stop docker-compose build --no-cache } docker_down() { docker_stop docker-compose down --remove-orphans } error() { echo -e "${RED}Error:${NORMAL} $1" } wait_for_db() { export PGPASSWORD=$POSTGRES_PASSWORD RETRIES=10 until psql -h $POSTGRES_HOST -U $POSTGRES_USER -d $POSTGRES_DB -c "select 1" > /dev/null 2>&1 || [ $RETRIES -eq 0 ]; do echo "Waiting for postgres server, $((RETRIES--)) remaining attempts..." sleep 5 done } # Commands intro() { echo echo echo "Development project:" echo echo " ${BOLD}init${NORMAL} initialize new dev project for development, do nothing if project already exists." echo " ${BOLD}clear${NORMAL} if dev project exists, delete it's files and destroy docker containers." echo " ${BOLD}rebuild${NORMAL} rebuild docker containers (uses --no-cache)." echo echo "Testing:" echo echo " ${BOLD}test${NORMAL} run tests suite." echo " ${BOLD}test module${NORMAL} run tests suite in specified python module, eg. misago.users." echo } invalid_option() { echo -e "Invalid option: ${RED}$1${NORMAL}" echo "Please run this script without any arguments to see the list of available options." exit 1 } # Initialize new dev project init() { for dev_path in "${dev_paths[@]}"; do if [ -e $dev_path ]; then error "Dev project already exists, or was not deleted completely." echo echo "Please use \"clear\" option to clear any pissible remaining files and try again." exit 1 fi done for port in "${required_ports[@]}"; do nc "127.0.0.1" "$port" < /dev/null if [[ $? = "0" ]]; then if [[ $port = $port_django ]]; then error "Django application appears to already be running on http://127.0.0.1:8000" elif [[ $port = $port_postgresql ]]; then error "PostgreSQL appears to already be running on port $port." fi exit 1 fi done docker_rebuild docker-compose run --rm misago ./dev init_in_docker } # Initialization step that has to occur inside docker init_in_docker() { wait_for_db # initialize django project python misago/bin/misago-start-devproject.py # move items of interest up one level mv devproject/devproject devproject_tmp mv devproject/avatargallery ./avatargallery mv devproject/media ./media mv devproject/userdata ./userdata mv devproject/manage.py ./manage.py rm -rf devproject mv devproject_tmp devproject # migrate the DB python manage.py migrate # create superuser Admin with password "password" python manage.py createsuperuser --username $username --email admin@example.com --password $password echo echo "================================================================================" echo echo "You can now start the development server using:" echo echo " docker-compose up" echo echo "Running server will be available in the browser under the http://127.0.0.1:8000 address." echo echo "Default superuser has been created with following credentials:" echo echo "Username: $username" echo "Password: $password" echo echo "To see development project configuration see files in the \"devproject\" directory." echo } # Clear existing dev project clear() { echo -e "${RED}Warning:${NORMAL} You are going clear current development project." echo will_delete_files=false for dev_path in "${dev_paths[@]}"; do if [ -e $dev_path ]; then will_delete_files=true fi done if [[ $will_delete_files = true ]]; then echo "Following files and directories will be deleted:" for dev_path in "${dev_paths[@]}"; do if [ -e $dev_path ]; then echo " $dev_path" fi done echo fi echo "This will also stop and remove docker containers used by this project." echo echo "Enter \"y\" to confirm:" read confirmation if [[ $confirmation = "y" ]]; then for dev_path in "${dev_paths[@]}"; do if [ -e $dev_path ]; then echo "Removing $dev_path" rm -rf $dev_path fi done docker-compose stop docker-compose down exit 0 else echo "Operation canceled." exit 0 fi } # Rebuild docker containers rebuild() { docker_rebuild exit 0 } # Run tests suite test() { $misago_run runtests.py $1 docker_stop exit 0 } # Command dispatcher if [[ $1 ]]; then if [[ $1 = "init" ]]; then init elif [[ $1 = "init_in_docker" ]]; then init_in_docker elif [[ $1 = "clear" ]]; then clear elif [[ $1 = "rebuild" ]]; then rebuild elif [[ $1 = "test" ]]; then test $2 else invalid_option $1 fi else intro fi