dev 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  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. }
  108. # Clear existing dev project
  109. clear() {
  110. echo -e "${RED}Warning:${NORMAL} You are going clear current development project."
  111. echo
  112. will_delete_files=false
  113. for dev_path in "${dev_paths[@]}"; do
  114. if [ -e $dev_path ]; then
  115. will_delete_files=true
  116. fi
  117. done
  118. if [[ $will_delete_files = true ]]; then
  119. echo "Following files and directories will be deleted:"
  120. for dev_path in "${dev_paths[@]}"; do
  121. if [ -e $dev_path ]; then
  122. echo " $dev_path"
  123. fi
  124. done
  125. echo
  126. fi
  127. echo "This will also stop and remove docker containers used by this project."
  128. echo
  129. echo "Enter \"y\" to confirm:"
  130. read confirmation
  131. if [[ $confirmation = "y" ]]; then
  132. for dev_path in "${dev_paths[@]}"; do
  133. if [ -e $dev_path ]; then
  134. echo "Removing $dev_path"
  135. rm -rf $dev_path
  136. fi
  137. done
  138. docker-compose stop
  139. docker-compose down
  140. exit 0
  141. else
  142. echo "Operation canceled."
  143. exit 0
  144. fi
  145. }
  146. # Rebuild docker containers
  147. rebuild() {
  148. docker_rebuild
  149. exit 0
  150. }
  151. # Run tests suite
  152. test() {
  153. $misago_run runtests.py $1
  154. docker_stop
  155. exit 0
  156. }
  157. # Command dispatcher
  158. if [[ $1 ]]; then
  159. if [[ $1 = "init" ]]; then
  160. init
  161. elif [[ $1 = "init_in_docker" ]]; then
  162. init_in_docker
  163. elif [[ $1 = "clear" ]]; then
  164. clear
  165. elif [[ $1 = "rebuild" ]]; then
  166. rebuild
  167. elif [[ $1 = "test" ]]; then
  168. test $2
  169. else
  170. invalid_option $1
  171. fi
  172. else
  173. intro
  174. fi