dev 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. #!/bin/bash
  2. # devctl is an utility script for automating some development tasks and actions.
  3. # To find out what options are available, run it without any arguments.
  4. # Text styles
  5. RED='\033[0;31m'
  6. BOLD=$(tput bold)
  7. NORMAL=$(tput sgr0)
  8. # Docker aliases
  9. misago_run="docker-compose run --rm misago"
  10. # Define dev paths
  11. # Those are paths to dirs and files created for dev project
  12. dev_paths=(
  13. "./avatargallery"
  14. "./devproject"
  15. "./media"
  16. "./static"
  17. "./theme"
  18. "./userdata"
  19. "./cron.txt"
  20. "./manage.py"
  21. )
  22. # Required ports
  23. # Some tasks test for those ports before continuing
  24. port_django=8000
  25. port_postgresql=5432
  26. required_ports=($port_postgresql)
  27. # Some commond shorthands
  28. docker_stop() {
  29. docker-compose stop
  30. }
  31. docker_rebuild() {
  32. docker_stop
  33. docker-compose build --no-cache
  34. }
  35. docker_down() {
  36. docker_stop
  37. docker-compose down --remove-orphans
  38. }
  39. error() {
  40. echo -e "${RED}Error:${NORMAL} $1"
  41. }
  42. wait_for_db() {
  43. export PGPASSWORD=$POSTGRES_PASSWORD
  44. RETRIES=10
  45. until psql -h $POSTGRES_HOST -U $POSTGRES_USER -d $POSTGRES_DB -c "select 1" > /dev/null 2>&1 || [ $RETRIES -eq 0 ]; do
  46. echo "Waiting for postgres server, $((RETRIES--)) remaining attempts..."
  47. sleep 5
  48. done
  49. }
  50. # Commands
  51. intro() {
  52. echo "Development project:"
  53. echo
  54. echo " ${BOLD}init${NORMAL} initialize new dev project for development, do nothing if project already exists."
  55. echo " ${BOLD}clear${NORMAL} if dev project exists, delete it's files and destroy docker containers."
  56. echo " ${BOLD}rebuild${NORMAL} rebuild docker containers (uses --no-cache)."
  57. echo
  58. echo "Testing:"
  59. echo
  60. echo " ${BOLD}test${NORMAL} run tests suite."
  61. echo " ${BOLD}test module${NORMAL} run tests suite in specified python module, eg. misago.users."
  62. }
  63. invalid_option() {
  64. echo -e "Invalid option: ${RED}$1${NORMAL}"
  65. echo "Please run this script without any arguments to see the list of available options."
  66. exit 1
  67. }
  68. # Initialize new dev project
  69. init() {
  70. for dev_path in "${dev_paths[@]}"; do
  71. if [ -e $dev_path ]; then
  72. error "Dev project already exists, or was not deleted completely."
  73. echo
  74. echo "Please use \"clear\" option to clear any pissible remaining files and try again."
  75. exit 1
  76. fi
  77. done
  78. for port in "${required_ports[@]}"; do
  79. nc "127.0.0.1" "$port" < /dev/null
  80. if [[ $? = "0" ]]; then
  81. if [[ $port = $port_django ]]; then
  82. error "Django application appears to already be running on http://127.0.0.1:8000"
  83. elif [[ $port = $port_postgresql ]]; then
  84. error "PostgreSQL appears to already be running on port $port."
  85. fi
  86. exit 1
  87. fi
  88. done
  89. docker_rebuild
  90. docker-compose run --rm misago ./dev init_in_docker
  91. }
  92. # Initialization step that has to occur inside docker
  93. init_in_docker() {
  94. wait_for_db
  95. # initialize django project
  96. python misago/bin/misago-start-devproject.py
  97. # move items of interest up one level
  98. mv devproject/devproject devproject_tmp
  99. mv devproject/avatargallery ./avatargallery
  100. mv devproject/media ./media
  101. mv devproject/userdata ./userdata
  102. mv devproject/manage.py ./manage.py
  103. rm -rf devproject
  104. mv devproject_tmp devproject
  105. # migrate the DB
  106. python manage.py migrate
  107. # create superuser Admin with password "password"
  108. python manage.py createsuperuser --username Admin --email admin@example.com --password password
  109. }
  110. # Clear existing dev project
  111. clear() {
  112. echo -e "${RED}Warning:${NORMAL} You are going clear current development project."
  113. echo
  114. will_delete_files=false
  115. for dev_path in "${dev_paths[@]}"; do
  116. if [ -e $dev_path ]; then
  117. will_delete_files=true
  118. fi
  119. done
  120. if [[ $will_delete_files = true ]]; then
  121. echo "Following files and directories will be deleted:"
  122. for dev_path in "${dev_paths[@]}"; do
  123. if [ -e $dev_path ]; then
  124. echo " $dev_path"
  125. fi
  126. done
  127. echo
  128. fi
  129. echo "This will also stop and remove docker containers used by this project."
  130. echo
  131. echo "Enter \"y\" to confirm:"
  132. read confirmation
  133. if [[ $confirmation = "y" ]]; then
  134. for dev_path in "${dev_paths[@]}"; do
  135. if [ -e $dev_path ]; then
  136. echo "Removing $dev_path"
  137. rm -rf $dev_path
  138. fi
  139. done
  140. docker-compose stop
  141. docker-compose down
  142. exit 0
  143. else
  144. echo "Operation canceled."
  145. exit 0
  146. fi
  147. }
  148. # Rebuild docker containers
  149. rebuild() {
  150. docker_rebuild
  151. exit 0
  152. }
  153. # Run tests suite
  154. test() {
  155. $misago_run runtests.py $1
  156. docker_stop
  157. exit 0
  158. }
  159. # Command dispatcher
  160. if [[ $1 ]]; then
  161. if [[ $1 = "init" ]]; then
  162. init
  163. elif [[ $1 = "init_in_docker" ]]; then
  164. init_in_docker
  165. elif [[ $1 = "clear" ]]; then
  166. clear
  167. elif [[ $1 = "rebuild" ]]; then
  168. rebuild
  169. elif [[ $1 = "test" ]]; then
  170. test $2
  171. else
  172. invalid_option $1
  173. fi
  174. else
  175. intro
  176. fi